diff options
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/at91/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/at91/clk-master.c | 2 | ||||
-rw-r--r-- | drivers/clk/at91/pmc.h | 2 | ||||
-rw-r--r-- | drivers/clk/at91/sam9x60.c | 649 | ||||
-rw-r--r-- | drivers/clk/at91/sama7g5.c | 4 | ||||
-rw-r--r-- | drivers/clk/renesas/Kconfig | 18 | ||||
-rw-r--r-- | drivers/clk/renesas/Makefile | 3 | ||||
-rw-r--r-- | drivers/clk/renesas/r8a774a1-cpg-mssr.c | 4 | ||||
-rw-r--r-- | drivers/clk/renesas/r8a774b1-cpg-mssr.c | 336 | ||||
-rw-r--r-- | drivers/clk/renesas/r8a774c0-cpg-mssr.c | 308 | ||||
-rw-r--r-- | drivers/clk/renesas/r8a774e1-cpg-mssr.c | 358 |
11 files changed, 1681 insertions, 4 deletions
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 2453c38af1a..580b406d7bd 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_AT91_GENERIC_CLK) += clk-generic.o obj-$(CONFIG_AT91_UTMI) += clk-utmi.o obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o obj-$(CONFIG_SAMA7G5) += sama7g5.o +obj-$(CONFIG_SAM9X60) += sam9x60.o else obj-y += compat.o endif diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 759df93697d..5d93e6a7e52 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -24,7 +24,7 @@ #define MASTER_PRES_MASK 0x7 #define MASTER_PRES_MAX MASTER_PRES_MASK #define MASTER_DIV_SHIFT 8 -#define MASTER_DIV_MASK 0x3 +#define MASTER_DIV_MASK 0x7 #define PMC_MCR 0x30 #define PMC_MCR_ID_MSK GENMASK(3, 0) diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index a6a714fd220..f07f535e492 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -30,7 +30,7 @@ extern const struct clk_master_layout at91sam9x5_master_layout; struct clk_master_characteristics { struct clk_range output; - u32 divisors[4]; + u32 divisors[5]; u8 have_div3_pres; }; diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c new file mode 100644 index 00000000000..c3235f565d7 --- /dev/null +++ b/drivers/clk/at91/sam9x60.c @@ -0,0 +1,649 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries + * + * Author: Claudiu Beznea <claudiu.beznea@microchip.com> + * + * Based on sam9x60.c on Linux. + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <dt-bindings/clk/at91.h> +#include <linux/clk-provider.h> + +#include "pmc.h" + +/** + * Clock identifiers to be used in conjunction with macros like + * AT91_TO_CLK_ID() + * + * @ID_MD_SLCK: TD slow clock identifier + * @ID_TD_SLCK: MD slow clock identifier + * @ID_MAIN_XTAL: Main Xtal clock identifier + * @ID_MAIN_RC: Main RC clock identifier + * @ID_MAIN_RC_OSC: Main RC Oscillator clock identifier + * @ID_MAIN_OSC: Main Oscillator clock identifier + * @ID_MAINCK: MAINCK clock identifier + * @ID_PLL_U_FRAC: UPLL fractional clock identifier + * @ID_PLL_U_DIV: UPLL divider clock identifier + * @ID_PLL_A_FRAC: APLL fractional clock identifier + * @ID_PLL_A_DIV: APLL divider clock identifier + + * @ID_MCK: MCK clock identifier + + * @ID_UTMI: UTMI clock identifier + + * @ID_PROG0: Programmable 0 clock identifier + * @ID_PROG1: Programmable 1 clock identifier + + * @ID_PCK0: PCK0 system clock identifier + * @ID_PCK1: PCK1 system clock identifier + * @ID_DDR: DDR system clock identifier + * @ID_QSPI: QSPI system clock identifier + * + * Note: if changing the values of this enums please sync them with + * device tree + */ +enum pmc_clk_ids { + ID_MD_SLCK = 0, + ID_TD_SLCK = 1, + ID_MAIN_XTAL = 2, + ID_MAIN_RC = 3, + ID_MAIN_RC_OSC = 4, + ID_MAIN_OSC = 5, + ID_MAINCK = 6, + + ID_PLL_U_FRAC = 7, + ID_PLL_U_DIV = 8, + ID_PLL_A_FRAC = 9, + ID_PLL_A_DIV = 10, + + ID_MCK = 11, + + ID_UTMI = 12, + + ID_PROG0 = 13, + ID_PROG1 = 14, + + ID_PCK0 = 15, + ID_PCK1 = 16, + + ID_DDR = 17, + ID_QSPI = 18, + + ID_MAX, +}; + +/** + * PLL type identifiers + * @PLL_TYPE_FRAC: fractional PLL identifier + * @PLL_TYPE_DIV: divider PLL identifier + */ +enum pll_type { + PLL_TYPE_FRAC, + PLL_TYPE_DIV, +}; + +/* Clock names used as parents for multiple clocks. */ +static const char *clk_names[] = { + [ID_MAIN_RC_OSC] = "main_rc_osc", + [ID_MAIN_OSC] = "main_osc", + [ID_MAINCK] = "mainck", + [ID_PLL_U_DIV] = "upll_divpmcck", + [ID_PLL_A_DIV] = "plla_divpmcck", + [ID_MCK] = "mck", +}; + +/* Fractional PLL output range. */ +static const struct clk_range plla_outputs[] = { + { .min = 2343750, .max = 1200000000 }, +}; + +static const struct clk_range upll_outputs[] = { + { .min = 300000000, .max = 500000000 }, +}; + +/* PLL characteristics. */ +static const struct clk_pll_characteristics apll_characteristics = { + .input = { .min = 12000000, .max = 48000000 }, + .num_output = ARRAY_SIZE(plla_outputs), + .output = plla_outputs, +}; + +static const struct clk_pll_characteristics upll_characteristics = { + .input = { .min = 12000000, .max = 48000000 }, + .num_output = ARRAY_SIZE(upll_outputs), + .output = upll_outputs, + .upll = true, +}; + +/* Layout for fractional PLLs. */ +static const struct clk_pll_layout pll_layout_frac = { + .mul_mask = GENMASK(31, 24), + .frac_mask = GENMASK(21, 0), + .mul_shift = 24, + .frac_shift = 0, +}; + +/* Layout for DIV PLLs. */ +static const struct clk_pll_layout pll_layout_div = { + .div_mask = GENMASK(7, 0), + .endiv_mask = BIT(29), + .div_shift = 0, + .endiv_shift = 29, +}; + +/* MCK characteristics. */ +static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 140000000, .max = 200000000 }, + .divisors = { 1, 2, 4, 3 }, + .have_div3_pres = 1, +}; + +/* MCK layout. */ +static const struct clk_master_layout mck_layout = { + .mask = 0x373, + .pres_shift = 4, + .offset = 0x28, +}; + +/* Programmable clock layout. */ +static const struct clk_programmable_layout programmable_layout = { + .pres_mask = 0xff, + .pres_shift = 8, + .css_mask = 0x1f, + .have_slck_mck = 0, + .is_pres_direct = 1, +}; + +/* Peripheral clock layout. */ +static const struct clk_pcr_layout pcr_layout = { + .offset = 0x88, + .cmd = BIT(31), + .gckcss_mask = GENMASK(12, 8), + .pid_mask = GENMASK(6, 0), +}; + +/** + * PLL clocks description + * @n: clock name + * @p: clock parent + * @l: clock layout + * @t: clock type + * @f: true if clock is fixed and not changeable by driver + * @id: clock id corresponding to PLL driver + * @cid: clock id corresponding to clock subsystem + */ +static const struct { + const char *n; + const char *p; + const struct clk_pll_layout *l; + const struct clk_pll_characteristics *c; + u8 t; + u8 f; + u8 id; + u8 cid; +} sam9x60_plls[] = { + { + .n = "plla_fracck", + .p = "mainck", + .l = &pll_layout_frac, + .c = &apll_characteristics, + .t = PLL_TYPE_FRAC, + .f = 1, + .id = 0, + .cid = ID_PLL_A_FRAC, + }, + + { + .n = "plla_divpmcck", + .p = "plla_fracck", + .l = &pll_layout_div, + .c = &apll_characteristics, + .t = PLL_TYPE_DIV, + .f = 1, + .id = 0, + .cid = ID_PLL_A_DIV, + }, + + { + .n = "upll_fracck", + .p = "main_osc", + .l = &pll_layout_frac, + .c = &upll_characteristics, + .t = PLL_TYPE_FRAC, + .f = 1, + .id = 1, + .cid = ID_PLL_U_FRAC, + }, + + { + .n = "upll_divpmcck", + .p = "upll_fracck", + .l = &pll_layout_div, + .c = &upll_characteristics, + .t = PLL_TYPE_DIV, + .f = 1, + .id = 1, + .cid = ID_PLL_U_DIV, + }, +}; + +/** + * Programmable clock description + * @n: clock name + * @cid: clock id corresponding to clock subsystem + */ +static const struct { + const char *n; + u8 cid; +} sam9x60_prog[] = { + { .n = "prog0", .cid = ID_PROG0, }, + { .n = "prog1", .cid = ID_PROG1, }, +}; + +/* Mux table for programmable clocks. */ +static u32 sam9x60_prog_mux_table[] = { 0, 1, 2, 3, 4, 5, }; + +/** + * System clock description + * @n: clock name + * @p: parent clock name + * @id: clock id corresponding to system clock driver + * @cid: clock id corresponding to clock subsystem + */ +static const struct { + const char *n; + const char *p; + u8 id; + u8 cid; +} sam9x60_systemck[] = { + { .n = "ddrck", .p = "mck", .id = 2, .cid = ID_DDR, }, + { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, }, + { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, }, + { .n = "qspick", .p = "mck", .id = 19, .cid = ID_QSPI, }, +}; + +/** + * Peripheral clock description + * @n: clock name + * @id: clock id + */ +static const struct { + const char *n; + u8 id; +} sam9x60_periphck[] = { + { .n = "pioA_clk", .id = 2, }, + { .n = "pioB_clk", .id = 3, }, + { .n = "pioC_clk", .id = 4, }, + { .n = "flex0_clk", .id = 5, }, + { .n = "flex1_clk", .id = 6, }, + { .n = "flex2_clk", .id = 7, }, + { .n = "flex3_clk", .id = 8, }, + { .n = "flex6_clk", .id = 9, }, + { .n = "flex7_clk", .id = 10, }, + { .n = "flex8_clk", .id = 11, }, + { .n = "sdmmc0_clk", .id = 12, }, + { .n = "flex4_clk", .id = 13, }, + { .n = "flex5_clk", .id = 14, }, + { .n = "flex9_clk", .id = 15, }, + { .n = "flex10_clk", .id = 16, }, + { .n = "tcb0_clk", .id = 17, }, + { .n = "pwm_clk", .id = 18, }, + { .n = "adc_clk", .id = 19, }, + { .n = "dma0_clk", .id = 20, }, + { .n = "matrix_clk", .id = 21, }, + { .n = "uhphs_clk", .id = 22, }, + { .n = "udphs_clk", .id = 23, }, + { .n = "macb0_clk", .id = 24, }, + { .n = "lcd_clk", .id = 25, }, + { .n = "sdmmc1_clk", .id = 26, }, + { .n = "macb1_clk", .id = 27, }, + { .n = "ssc_clk", .id = 28, }, + { .n = "can0_clk", .id = 29, }, + { .n = "can1_clk", .id = 30, }, + { .n = "flex11_clk", .id = 32, }, + { .n = "flex12_clk", .id = 33, }, + { .n = "i2s_clk", .id = 34, }, + { .n = "qspi_clk", .id = 35, }, + { .n = "gfx2d_clk", .id = 36, }, + { .n = "pit64b_clk", .id = 37, }, + { .n = "trng_clk", .id = 38, }, + { .n = "aes_clk", .id = 39, }, + { .n = "tdes_clk", .id = 40, }, + { .n = "sha_clk", .id = 41, }, + { .n = "classd_clk", .id = 42, }, + { .n = "isi_clk", .id = 43, }, + { .n = "pioD_clk", .id = 44, }, + { .n = "tcb1_clk", .id = 45, }, + { .n = "dbgu_clk", .id = 47, }, + { .n = "mpddr_clk", .id = 49, }, +}; + +/** + * Generic clock description + * @n: clock name + * @ep: extra parents parents names + * @ep_mux_table: extra parents mux table + * @ep_clk_mux_table: extra parents clock mux table (for CCF) + * @r: clock output range + * @ep_count: extra parents count + * @id: clock id + */ +static const struct { + const char *n; + struct clk_range r; + u8 id; +} sam9x60_gck[] = { + { .n = "flex0_gclk", .id = 5, }, + { .n = "flex1_gclk", .id = 6, }, + { .n = "flex2_gclk", .id = 7, }, + { .n = "flex3_gclk", .id = 8, }, + { .n = "flex6_gclk", .id = 9, }, + { .n = "flex7_gclk", .id = 10, }, + { .n = "flex8_gclk", .id = 11, }, + { .n = "sdmmc0_gclk", .id = 12, .r = { .min = 0, .max = 105000000 }, }, + { .n = "flex4_gclk", .id = 13, }, + { .n = "flex5_gclk", .id = 14, }, + { .n = "flex9_gclk", .id = 15, }, + { .n = "flex10_gclk", .id = 16, }, + { .n = "tcb0_gclk", .id = 17, }, + { .n = "adc_gclk", .id = 19, }, + { .n = "lcd_gclk", .id = 25, .r = { .min = 0, .max = 140000000 }, }, + { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, }, + { .n = "flex11_gclk", .id = 32, }, + { .n = "flex12_gclk", .id = 33, }, + { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, }, + { .n = "pit64b_gclk", .id = 37, }, + { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, }, + { .n = "tcb1_gclk", .id = 45, }, + { .n = "dbgu_gclk", .id = 47, }, +}; + +#define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \ + do { \ + int _i; \ + (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \ + if (!(_dst)) { \ + ret = -ENOMEM; \ + goto _label; \ + } \ + (_allocs)[(_index)++] = (_dst); \ + for (_i = 0; _i < (_num); _i++) \ + (_dst)[_i] = (_src)[_i]; \ + } while (0) + +static int sam9x60_clk_probe(struct udevice *dev) +{ + void __iomem *base = (void *)devfdt_get_addr_ptr(dev); + unsigned int *clkmuxallocs[64], *muxallocs[64]; + const char *p[10]; + unsigned int cm[10], m[10], *tmpclkmux, *tmpmux; + struct clk clk, *c; + bool main_osc_bypass; + int ret, muxallocindex = 0, clkmuxallocindex = 0, i; + static const struct clk_range r = { 0, 0 }; + + if (!base) + return -EINVAL; + + memset(muxallocs, 0, ARRAY_SIZE(muxallocs)); + memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs)); + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + ret = clk_get_by_id(clk.id, &c); + if (ret) + return ret; + + clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c), + strlen(clk_hw_get_name(c)) + 1, + GFP_KERNEL); + if (!clk_names[ID_TD_SLCK]) + return -ENOMEM; + + ret = clk_get_by_index(dev, 1, &clk); + if (ret) + return ret; + + ret = clk_get_by_id(clk.id, &c); + if (ret) + return ret; + + clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c), + strlen(clk_hw_get_name(c)) + 1, + GFP_KERNEL); + if (!clk_names[ID_MD_SLCK]) + return -ENOMEM; + + ret = clk_get_by_index(dev, 2, &clk); + if (ret) + return ret; + + clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk), + strlen(clk_hw_get_name(&clk)) + 1, + GFP_KERNEL); + if (!clk_names[ID_MAIN_XTAL]) + return -ENOMEM; + + ret = clk_get_by_index(dev, 3, &clk); + if (ret) + goto fail; + + clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk), + strlen(clk_hw_get_name(&clk)) + 1, + GFP_KERNEL); + if (ret) + goto fail; + + main_osc_bypass = dev_read_bool(dev, "atmel,main-osc-bypass"); + + /* Register main rc oscillator. */ + c = at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC], + clk_names[ID_MAIN_RC]); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC), c); + + /* Register main oscillator. */ + c = at91_clk_main_osc(base, clk_names[ID_MAIN_OSC], + clk_names[ID_MAIN_XTAL], main_osc_bypass); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC), c); + + /* Register mainck. */ + p[0] = clk_names[ID_MAIN_RC_OSC]; + p[1] = clk_names[ID_MAIN_OSC]; + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC); + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC); + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2, + fail); + c = at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p, + 2, tmpclkmux, PMC_TYPE_CORE); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK), c); + + /* Register PLL fracs clocks. */ + for (i = 0; i < ARRAY_SIZE(sam9x60_plls); i++) { + if (sam9x60_plls[i].t != PLL_TYPE_FRAC) + continue; + + c = sam9x60_clk_register_frac_pll(base, sam9x60_plls[i].n, + sam9x60_plls[i].p, + sam9x60_plls[i].id, + sam9x60_plls[i].c, + sam9x60_plls[i].l, + sam9x60_plls[i].f); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c); + } + + /* Register PLL div clocks. */ + for (i = 0; i < ARRAY_SIZE(sam9x60_plls); i++) { + if (sam9x60_plls[i].t != PLL_TYPE_DIV) + continue; + + c = sam9x60_clk_register_div_pll(base, sam9x60_plls[i].n, + sam9x60_plls[i].p, + sam9x60_plls[i].id, + sam9x60_plls[i].c, + sam9x60_plls[i].l, + sam9x60_plls[i].f); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c); + } + + /* Register MCK clock. */ + p[0] = clk_names[ID_MD_SLCK]; + p[1] = clk_names[ID_MAINCK]; + p[2] = clk_names[ID_PLL_A_DIV]; + p[3] = clk_names[ID_PLL_U_DIV]; + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); + cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); + cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4, + fail); + c = at91_clk_register_master(base, clk_names[ID_MCK], p, 4, &mck_layout, + &mck_characteristics, tmpclkmux); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK), c); + + /* Register programmable clocks. */ + p[0] = clk_names[ID_MD_SLCK]; + p[1] = clk_names[ID_TD_SLCK]; + p[2] = clk_names[ID_MAINCK]; + p[3] = clk_names[ID_MCK]; + p[4] = clk_names[ID_PLL_A_DIV]; + p[5] = clk_names[ID_PLL_U_DIV]; + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); + cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); + cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK); + cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); + cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); + for (i = 0; i < ARRAY_SIZE(sam9x60_prog); i++) { + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, + 6, fail); + + c = at91_clk_register_programmable(base, sam9x60_prog[i].n, p, + 10, i, &programmable_layout, + tmpclkmux, + sam9x60_prog_mux_table); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_prog[i].cid), c); + } + + /* System clocks. */ + for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) { + c = at91_clk_register_system(base, sam9x60_systemck[i].n, + sam9x60_systemck[i].p, + sam9x60_systemck[i].id); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sam9x60_systemck[i].cid), + c); + } + + /* Peripheral clocks. */ + for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) { + c = at91_clk_register_sam9x5_peripheral(base, &pcr_layout, + sam9x60_periphck[i].n, + clk_names[ID_MCK], + sam9x60_periphck[i].id, + &r); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL, + sam9x60_periphck[i].id), c); + } + + /* Generic clocks. */ + p[0] = clk_names[ID_MD_SLCK]; + p[1] = clk_names[ID_TD_SLCK]; + p[2] = clk_names[ID_MAINCK]; + p[3] = clk_names[ID_MCK]; + p[4] = clk_names[ID_PLL_A_DIV]; + p[5] = clk_names[ID_PLL_U_DIV]; + m[0] = 0; + m[1] = 1; + m[2] = 2; + m[3] = 3; + m[4] = 4; + m[5] = 5; + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); + cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); + cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK); + cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); + cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); + for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) { + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, + 6, fail); + prepare_mux_table(muxallocs, muxallocindex, tmpmux, m, + 6, fail); + + c = at91_clk_register_generic(base, &pcr_layout, + sam9x60_gck[i].n, p, tmpclkmux, + tmpmux, 6, sam9x60_gck[i].id, + &sam9x60_gck[i].r); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto fail; + } + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sam9x60_gck[i].id), c); + } + + return 0; + +fail: + for (i = 0; i < ARRAY_SIZE(muxallocs); i++) + kfree(muxallocs[i]); + + for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++) + kfree(clkmuxallocs[i]); + + return ret; +} + +static const struct udevice_id sam9x60_clk_ids[] = { + { .compatible = "microchip,sam9x60-pmc" }, + { /* Sentinel. */ }, +}; + +U_BOOT_DRIVER(at91_sam9x60_pmc) = { + .name = "at91-sam9x60-pmc", + .id = UCLASS_CLK, + .of_match = sam9x60_clk_ids, + .ops = &at91_clk_ops, + .probe = sam9x60_clk_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c index b96937673be..c0d9271966d 100644 --- a/drivers/clk/at91/sama7g5.c +++ b/drivers/clk/at91/sama7g5.c @@ -189,13 +189,13 @@ static const struct clk_pll_layout pll_layout_divio = { /* MCK0 characteristics. */ static const struct clk_master_characteristics mck0_characteristics = { .output = { .min = 140000000, .max = 200000000 }, - .divisors = { 1, 2, 4, 3 }, + .divisors = { 1, 2, 4, 3, 5 }, .have_div3_pres = 1, }; /* MCK0 layout. */ static const struct clk_master_layout mck0_layout = { - .mask = 0x373, + .mask = 0x773, .pres_shift = 4, .offset = 0x28, }; diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 284e2138b39..0c8b9eb47de 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -55,6 +55,24 @@ config CLK_R8A774A1 help Enable this to support the clocks on Renesas R8A774A1 SoC. +config CLK_R8A774B1 + bool "Renesas R8A774B1 clock driver" + depends on CLK_RCAR_GEN3 + help + Enable this to support the clocks on Renesas R8A774B1 SoC. + +config CLK_R8A774C0 + bool "Renesas R8A774C0 clock driver" + depends on CLK_RCAR_GEN3 + help + Enable this to support the clocks on Renesas R8A774C0 SoC. + +config CLK_R8A774E1 + bool "Renesas R8A774E1 clock driver" + depends on CLK_RCAR_GEN3 + help + Enable this to support the clocks on Renesas R8A774E1 SoC. + config CLK_R8A7795 bool "Renesas R8A7795 clock driver" depends on CLK_RCAR_GEN3 diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index dd599b757e8..ed1a1252c40 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -1,6 +1,9 @@ obj-$(CONFIG_CLK_RENESAS) += renesas-cpg-mssr.o obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774E1) += r8a774e1-cpg-mssr.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o obj-$(CONFIG_CLK_R8A7791) += r8a7791-cpg-mssr.o obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c index 8935667736f..6997054b304 100644 --- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -41,6 +41,7 @@ enum clk_ids { CLK_S2, CLK_S3, CLK_SDSRC, + CLK_RPCSRC, CLK_RINT, /* Module Clocks */ @@ -67,6 +68,7 @@ static const struct cpg_core_clk r8a774a1_core_clks[] = { DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".rpcsrc", CLK_RPCSRC, CLK_PLL1, 2, 1), DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), @@ -97,6 +99,7 @@ static const struct cpg_core_clk r8a774a1_core_clks[] = { DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078), DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268), DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c), + DEF_GEN3_RPC("rpc", R8A774A1_CLK_RPC, CLK_RPCSRC, 0x238), DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1), @@ -200,6 +203,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] = { DEF_MOD("can-fd", 914, R8A774A1_CLK_S3D2), DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4), DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4), + DEF_MOD("rpc", 917, R8A774A1_CLK_RPC), DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP), diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c new file mode 100644 index 00000000000..7b6947b5b90 --- /dev/null +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774b1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2020 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> + +#include <dt-bindings/clock/r8a774b1-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774B1_CLK_CANFD, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774b1_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_GEN3_Z("z", R8A774B1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8), + DEF_FIXED("ztr", R8A774B1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774B1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774B1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774B1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774B1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774B1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774B1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774B1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774B1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774B1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774B1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774B1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774B1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774B1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774B1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774B1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774B1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774B1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774B1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774B1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A774B1_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774B1_CLK_CPEX, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("canfd", R8A774B1_CLK_CANFD, CLK_PLL1_DIV4, 0x244), + DEF_DIV6P1("csi0", R8A774B1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774B1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774B1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774B1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774B1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774b1_mod_clks[] = { + DEF_MOD("tmu4", 121, R8A774B1_CLK_S0D6), + DEF_MOD("tmu3", 122, R8A774B1_CLK_S3D2), + DEF_MOD("tmu2", 123, R8A774B1_CLK_S3D2), + DEF_MOD("tmu1", 124, R8A774B1_CLK_S3D2), + DEF_MOD("tmu0", 125, R8A774B1_CLK_CP), + DEF_MOD("fdp1-0", 119, R8A774B1_CLK_S0D1), + DEF_MOD("scif5", 202, R8A774B1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774B1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774B1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774B1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774B1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774B1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774B1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774B1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774B1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774B1_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774B1_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774B1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774B1_CLK_R), + DEF_MOD("cmt2", 301, R8A774B1_CLK_R), + DEF_MOD("cmt1", 302, R8A774B1_CLK_R), + DEF_MOD("cmt0", 303, R8A774B1_CLK_R), + DEF_MOD("tpu0", 304, R8A774B1_CLK_S3D4), + DEF_MOD("scif2", 310, R8A774B1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774B1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774B1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774B1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774B1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774B1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774B1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774B1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774B1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774B1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774B1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774B1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774B1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774B1_CLK_S1D2), + DEF_MOD("audmac0", 502, R8A774B1_CLK_S1D2), + DEF_MOD("hscif4", 516, R8A774B1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774B1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774B1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774B1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774B1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774B1_CLK_CP), + DEF_MOD("pwm", 523, R8A774B1_CLK_S0D12), + DEF_MOD("fcpvd1", 602, R8A774B1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774B1_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A774B1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774B1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774B1_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774B1_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A774B1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774B1_CLK_S0D2), + DEF_MOD("vspb", 626, R8A774B1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774B1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774B1_CLK_S3D2), + DEF_MOD("ehci0", 703, R8A774B1_CLK_S3D2), + DEF_MOD("hsusb", 704, R8A774B1_CLK_S3D2), + DEF_MOD("csi20", 714, R8A774B1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774B1_CLK_CSI0), + DEF_MOD("du3", 721, R8A774B1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774B1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774B1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774B1_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A774B1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774B1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774B1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774B1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774B1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774B1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774B1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774B1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774B1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774B1_CLK_S0D6), + DEF_MOD("sata0", 815, R8A774B1_CLK_S3D2), + DEF_MOD("gpio7", 905, R8A774B1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774B1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774B1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774B1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774B1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774B1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774B1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774B1_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A774B1_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A774B1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774B1_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774B1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774B1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774B1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774B1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774B1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774B1_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774B1_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *----------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +/* RMSTPCR[0-11] is not present on RZ/G2N */ +static const struct mstp_stop_table r8a774b1_mstp_table[] = { + { 0x00200000, 0x0, 0x0, 0 }, + { 0xFFFFFFFF, 0x0, 0x0, 0 }, + { 0x340E2FDC, 0x2040, 0x0, 0 }, + { 0xFFFFFFDF, 0x400, 0x0, 0 }, + { 0x80000184, 0x180, 0x0, 0 }, + { 0xC3FFFFFF, 0x0, 0x0, 0 }, + { 0xFFFFFFFF, 0x0, 0x0, 0 }, + { 0xFFFFFFFF, 0x0, 0x0, 0 }, + { 0x01F1FFF7, 0x0, 0x0, 0 }, + { 0xFFFFFFFE, 0x0, 0x0, 0 }, + { 0xFFFEFFE0, 0x0, 0x0, 0 }, + { 0x000000B7, 0x0, 0x0, 0 }, +}; + +static const void *r8a774b1_get_pll_config(const u32 cpg_mode) +{ + return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; +} + +static const struct cpg_mssr_info r8a774b1_cpg_mssr_info = { + .core_clk = r8a774b1_core_clks, + .core_clk_size = ARRAY_SIZE(r8a774b1_core_clks), + .mod_clk = r8a774b1_mod_clks, + .mod_clk_size = ARRAY_SIZE(r8a774b1_mod_clks), + .mstp_table = r8a774b1_mstp_table, + .mstp_table_size = ARRAY_SIZE(r8a774b1_mstp_table), + .reset_node = "renesas,r8a774b1-rst", + .extalr_node = "extalr", + .mod_clk_base = MOD_CLK_BASE, + .clk_extal_id = CLK_EXTAL, + .clk_extalr_id = CLK_EXTALR, + .get_pll_config = r8a774b1_get_pll_config, +}; + +static const struct udevice_id r8a774b1_clk_ids[] = { + { + .compatible = "renesas,r8a774b1-cpg-mssr", + .data = (ulong)&r8a774b1_cpg_mssr_info, + }, + { } +}; + +U_BOOT_DRIVER(clk_r8a774b1) = { + .name = "clk_r8a774b1", + .id = UCLASS_CLK, + .of_match = r8a774b1_clk_ids, + .priv_auto_alloc_size = sizeof(struct gen3_clk_priv), + .ops = &gen3_clk_ops, + .probe = gen3_clk_probe, + .remove = gen3_clk_remove, +}; diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c new file mode 100644 index 00000000000..c9f0f7221d7 --- /dev/null +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774c0 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2020 Renesas Electronics Corp. + * + * Based on r8a77990-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <linux/bitops.h> + +#include <dt-bindings/clock/r8a774c0-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774C0_CLK_CANFD, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL0D4, + CLK_PLL0D6, + CLK_PLL0D8, + CLK_PLL0D20, + CLK_PLL0D24, + CLK_PLL1D2, + CLK_PE, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + CLK_OCO, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774c0_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + + DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100), + DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1), + DEF_FIXED(".pll0d6", CLK_PLL0D6, CLK_PLL0, 6, 1), + DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1), + DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1), + DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1), + DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), + DEF_FIXED(".pe", CLK_PE, CLK_PLL0D20, 1, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), + + /* Core Clock Outputs */ + DEF_FIXED("za2", R8A774C0_CLK_ZA2, CLK_PLL0D24, 1, 1), + DEF_FIXED("za8", R8A774C0_CLK_ZA8, CLK_PLL0D8, 1, 1), + DEF_GEN3_Z("z2", R8A774C0_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL0, 4, 8), + DEF_FIXED("ztr", R8A774C0_CLK_ZTR, CLK_PLL1, 6, 1), + DEF_FIXED("zt", R8A774C0_CLK_ZT, CLK_PLL1, 4, 1), + DEF_FIXED("zx", R8A774C0_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("s0d1", R8A774C0_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d3", R8A774C0_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d6", R8A774C0_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d12", R8A774C0_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s0d24", R8A774C0_CLK_S0D24, CLK_S0, 24, 1), + DEF_FIXED("s1d1", R8A774C0_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A774C0_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774C0_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774C0_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774C0_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774C0_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774C0_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774C0_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774C0_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, CLK_SDSRC, 0x026c), + + DEF_FIXED("cl", R8A774C0_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A774C0_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774C0_CLK_CPEX, CLK_EXTAL, 4, 1), + + DEF_DIV6_RO("osc", R8A774C0_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + + DEF_GEN3_PE("s0d6c", R8A774C0_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2), + DEF_GEN3_PE("s3d1c", R8A774C0_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), + DEF_GEN3_PE("s3d2c", R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), + DEF_GEN3_PE("s3d4c", R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), + + DEF_DIV6P1("canfd", R8A774C0_CLK_CANFD, CLK_PLL0D6, 0x244), + DEF_DIV6P1("csi0", R8A774C0_CLK_CSI0, CLK_PLL1D2, 0x00c), + DEF_DIV6P1("mso", R8A774C0_CLK_MSO, CLK_PLL1D2, 0x014), + + DEF_GEN3_RCKSEL("r", R8A774C0_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4), +}; + +static const struct mssr_mod_clk r8a774c0_mod_clks[] = { + DEF_MOD("tmu4", 121, R8A774C0_CLK_S0D6C), + DEF_MOD("tmu3", 122, R8A774C0_CLK_S3D2C), + DEF_MOD("tmu2", 123, R8A774C0_CLK_S3D2C), + DEF_MOD("tmu1", 124, R8A774C0_CLK_S3D2C), + DEF_MOD("tmu0", 125, R8A774C0_CLK_CP), + DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C), + DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C), + DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C), + DEF_MOD("scif1", 206, R8A774C0_CLK_S3D4C), + DEF_MOD("scif0", 207, R8A774C0_CLK_S3D4C), + DEF_MOD("msiof3", 208, R8A774C0_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774C0_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774C0_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774C0_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774C0_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774C0_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774C0_CLK_S3D1), + + DEF_MOD("cmt3", 300, R8A774C0_CLK_R), + DEF_MOD("cmt2", 301, R8A774C0_CLK_R), + DEF_MOD("cmt1", 302, R8A774C0_CLK_R), + DEF_MOD("cmt0", 303, R8A774C0_CLK_R), + DEF_MOD("scif2", 310, R8A774C0_CLK_S3D4C), + DEF_MOD("sdif3", 311, R8A774C0_CLK_SD3), + DEF_MOD("sdif1", 313, R8A774C0_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774C0_CLK_SD0), + DEF_MOD("pcie0", 319, R8A774C0_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774C0_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774C0_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774C0_CLK_S3D1), + + DEF_MOD("rwdt", 402, R8A774C0_CLK_R), + DEF_MOD("intc-ex", 407, R8A774C0_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774C0_CLK_S0D3), + + DEF_MOD("audmac0", 502, R8A774C0_CLK_S1D2), + DEF_MOD("hscif4", 516, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif3", 517, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif2", 518, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif1", 519, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif0", 520, R8A774C0_CLK_S3D1C), + DEF_MOD("thermal", 522, R8A774C0_CLK_CP), + DEF_MOD("pwm", 523, R8A774C0_CLK_S3D4C), + + DEF_MOD("fcpvd1", 602, R8A774C0_CLK_S1D2), + DEF_MOD("fcpvd0", 603, R8A774C0_CLK_S1D2), + DEF_MOD("fcpvb0", 607, R8A774C0_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774C0_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774C0_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774C0_CLK_S0D1), + DEF_MOD("vspd1", 622, R8A774C0_CLK_S1D2), + DEF_MOD("vspd0", 623, R8A774C0_CLK_S1D2), + DEF_MOD("vspb", 626, R8A774C0_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774C0_CLK_S0D1), + + DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D2), + DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D2), + DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0), + DEF_MOD("du1", 723, R8A774C0_CLK_S1D1), + DEF_MOD("du0", 724, R8A774C0_CLK_S1D1), + DEF_MOD("lvds", 727, R8A774C0_CLK_S2D1), + + DEF_MOD("vin5", 806, R8A774C0_CLK_S1D2), + DEF_MOD("vin4", 807, R8A774C0_CLK_S1D2), + DEF_MOD("etheravb", 812, R8A774C0_CLK_S3D2), + + DEF_MOD("gpio6", 906, R8A774C0_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774C0_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774C0_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774C0_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774C0_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774C0_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774C0_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A774C0_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), + DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2), + DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP), + DEF_MOD("i2c4", 927, R8A774C0_CLK_S3D2), + DEF_MOD("i2c3", 928, R8A774C0_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A774C0_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774C0_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774C0_CLK_S3D2), + + DEF_MOD("i2c7", 1003, R8A774C0_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774C0_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774C0_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +/* + * CPG Clock Data + */ + +/* + * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 + *-------------------------------------------------------------------- + * 0 48 x 1 x100/1 x100/3 x100/3 + * 1 48 x 1 x100/1 x100/3 x58/3 + */ +#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 100, 3, 100, 3, }, + { 1, 100, 3, 58, 3, }, +}; + +static const struct mstp_stop_table r8a774c0_mstp_table[] = { + { 0x00200000, 0x0, 0x00200000, 0 }, + { 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 }, + { 0x340E2FDC, 0x2040, 0x340E2FDC, 0 }, + { 0xFFFFFFDF, 0x400, 0xFFFFFFDF, 0 }, + { 0x80000184, 0x180, 0x80000184, 0 }, + { 0xC3FFFFFF, 0x0, 0xC3FFFFFF, 0 }, + { 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 }, + { 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 }, + { 0x01F1FFF7, 0x0, 0x01F1FFF7, 0 }, + { 0xFFFFFFFE, 0x0, 0xFFFFFFFE, 0 }, + { 0xFFFEFFE0, 0x0, 0xFFFEFFE0, 0 }, + { 0x000000B7, 0x0, 0x000000B7, 0 }, +}; + +static const void *r8a774c0_get_pll_config(const u32 cpg_mode) +{ + return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; +} + +const struct cpg_mssr_info r8a774c0_cpg_mssr_info = { + .core_clk = r8a774c0_core_clks, + .core_clk_size = ARRAY_SIZE(r8a774c0_core_clks), + .mod_clk = r8a774c0_mod_clks, + .mod_clk_size = ARRAY_SIZE(r8a774c0_mod_clks), + .mstp_table = r8a774c0_mstp_table, + .mstp_table_size = ARRAY_SIZE(r8a774c0_mstp_table), + .reset_node = "renesas,r8a774c0-rst", + .mod_clk_base = MOD_CLK_BASE, + .clk_extal_id = CLK_EXTAL, + .clk_extalr_id = ~0, + .get_pll_config = r8a774c0_get_pll_config, +}; + +static const struct udevice_id r8a774c0_clk_ids[] = { + { + .compatible = "renesas,r8a774c0-cpg-mssr", + .data = (ulong)&r8a774c0_cpg_mssr_info + }, + { } +}; + +U_BOOT_DRIVER(clk_r8a774c0) = { + .name = "clk_r8a774c0", + .id = UCLASS_CLK, + .of_match = r8a774c0_clk_ids, + .priv_auto_alloc_size = sizeof(struct gen3_clk_priv), + .ops = &gen3_clk_ops, + .probe = gen3_clk_probe, + .remove = gen3_clk_remove, +}; diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c new file mode 100644 index 00000000000..6cce007aa13 --- /dev/null +++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774e1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2020 Renesas Electronics Corp. + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <linux/bitops.h> + +#include <dt-bindings/clock/r8a774e1-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774E1_CLK_CANFD, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RPCSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774e1_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1), + + DEF_BASE("rpc", R8A774E1_CLK_RPC, CLK_TYPE_GEN3_RPC, + CLK_RPCSRC), + DEF_BASE("rpcd2", R8A774E1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, + R8A774E1_CLK_RPC), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_GEN3_Z("z", R8A774E1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8), + DEF_GEN3_Z("z2", R8A774E1_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0), + DEF_FIXED("ztr", R8A774E1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774E1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774E1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774E1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774E1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774E1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774E1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774E1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774E1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774E1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774E1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774E1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774E1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774E1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774E1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774E1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774E1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774E1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774E1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774E1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cr", R8A774E1_CLK_CR, CLK_PLL1_DIV4, 2, 1), + DEF_FIXED("cp", R8A774E1_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774E1_CLK_CPEX, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("canfd", R8A774E1_CLK_CANFD, CLK_PLL1_DIV4, 0x244), + DEF_DIV6P1("csi0", R8A774E1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774E1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774E1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774E1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774E1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774e1_mod_clks[] = { + DEF_MOD("fdp1-1", 118, R8A774E1_CLK_S0D1), + DEF_MOD("fdp1-0", 119, R8A774E1_CLK_S0D1), + DEF_MOD("tmu4", 121, R8A774E1_CLK_S0D6), + DEF_MOD("tmu3", 122, R8A774E1_CLK_S3D2), + DEF_MOD("tmu2", 123, R8A774E1_CLK_S3D2), + DEF_MOD("tmu1", 124, R8A774E1_CLK_S3D2), + DEF_MOD("tmu0", 125, R8A774E1_CLK_CP), + DEF_MOD("vcplf", 130, R8A774E1_CLK_S2D1), + DEF_MOD("vdpb", 131, R8A774E1_CLK_S2D1), + DEF_MOD("scif5", 202, R8A774E1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774E1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774E1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774E1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774E1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774E1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774E1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774E1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774E1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774E1_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774E1_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774E1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774E1_CLK_R), + DEF_MOD("cmt2", 301, R8A774E1_CLK_R), + DEF_MOD("cmt1", 302, R8A774E1_CLK_R), + DEF_MOD("cmt0", 303, R8A774E1_CLK_R), + DEF_MOD("tpu0", 304, R8A774E1_CLK_S3D4), + DEF_MOD("scif2", 310, R8A774E1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774E1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774E1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774E1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774E1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774E1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774E1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774E1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774E1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774E1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774E1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774E1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774E1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774E1_CLK_S1D2), + DEF_MOD("audmac0", 502, R8A774E1_CLK_S1D2), + DEF_MOD("hscif4", 516, R8A774E1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774E1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774E1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774E1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774E1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774E1_CLK_CP), + DEF_MOD("pwm", 523, R8A774E1_CLK_S0D12), + DEF_MOD("fcpvd1", 602, R8A774E1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774E1_CLK_S0D2), + DEF_MOD("fcpvb1", 606, R8A774E1_CLK_S0D1), + DEF_MOD("fcpvb0", 607, R8A774E1_CLK_S0D1), + DEF_MOD("fcpvi1", 610, R8A774E1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774E1_CLK_S0D1), + DEF_MOD("fcpf1", 614, R8A774E1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774E1_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774E1_CLK_S0D1), + DEF_MOD("vspd1", 622, R8A774E1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774E1_CLK_S0D2), + DEF_MOD("vspbc", 624, R8A774E1_CLK_S0D1), + DEF_MOD("vspbd", 626, R8A774E1_CLK_S0D1), + DEF_MOD("vspi1", 630, R8A774E1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774E1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774E1_CLK_S3D2), + DEF_MOD("ehci0", 703, R8A774E1_CLK_S3D2), + DEF_MOD("hsusb", 704, R8A774E1_CLK_S3D2), + DEF_MOD("csi20", 714, R8A774E1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774E1_CLK_CSI0), + DEF_MOD("du3", 721, R8A774E1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774E1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774E1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774E1_CLK_S0D4), + DEF_MOD("hdmi0", 729, R8A774E1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774E1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774E1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774E1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774E1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774E1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774E1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774E1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774E1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774E1_CLK_S0D6), + DEF_MOD("sata0", 815, R8A774E1_CLK_S3D2), + DEF_MOD("gpio7", 905, R8A774E1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774E1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774E1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774E1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774E1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774E1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774E1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774E1_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A774E1_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A774E1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774E1_CLK_S3D4), + DEF_MOD("rpc-if", 917, R8A774E1_CLK_RPCD2), + DEF_MOD("i2c6", 918, R8A774E1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774E1_CLK_S0D6), + DEF_MOD("adg", 922, R8A774E1_CLK_S0D1), + DEF_MOD("i2c-dvfs", 926, R8A774E1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774E1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774E1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774E1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774E1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774E1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774E1_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774E1_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +/* RMSTPCR[0-11] is not present on RZ/G2H */ +static const struct mstp_stop_table r8a774e1_mstp_table[] = { + { 0x00640800, 0x0, 0x0, 0 }, + { 0xF3EE9390, 0x0, 0x0, 0 }, + { 0x340FAFDC, 0x2040, 0x0, 0 }, + { 0xD80C7CDF, 0x400, 0x0, 0 }, + { 0x80000184, 0x180, 0x0, 0 }, + { 0x40BFFF46, 0x0, 0x0, 0 }, + { 0xE5FBEECF, 0x0, 0x0, 0 }, + { 0x39FFFF0E, 0x0, 0x0, 0 }, + { 0x01F19FF4, 0x0, 0x0, 0 }, + { 0xFFDFFFFF, 0x0, 0x0, 0 }, + { 0xFFFEFFE0, 0x0, 0x0, 0 }, + { 0x00000000, 0x0, 0x0, 0 }, +}; + +static const void *r8a774e1_get_pll_config(const u32 cpg_mode) +{ + return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; +} + +static const struct cpg_mssr_info r8a774e1_cpg_mssr_info = { + .core_clk = r8a774e1_core_clks, + .core_clk_size = ARRAY_SIZE(r8a774e1_core_clks), + .mod_clk = r8a774e1_mod_clks, + .mod_clk_size = ARRAY_SIZE(r8a774e1_mod_clks), + .mstp_table = r8a774e1_mstp_table, + .mstp_table_size = ARRAY_SIZE(r8a774e1_mstp_table), + .reset_node = "renesas,r8a774e1-rst", + .extalr_node = "extalr", + .mod_clk_base = MOD_CLK_BASE, + .clk_extal_id = CLK_EXTAL, + .clk_extalr_id = CLK_EXTALR, + .get_pll_config = r8a774e1_get_pll_config, +}; + +static const struct udevice_id r8a774e1_clk_ids[] = { + { + .compatible = "renesas,r8a774e1-cpg-mssr", + .data = (ulong)&r8a774e1_cpg_mssr_info + }, + { } +}; + +U_BOOT_DRIVER(clk_r8a774e1) = { + .name = "clk_r8a774e1", + .id = UCLASS_CLK, + .of_match = r8a774e1_clk_ids, + .priv_auto_alloc_size = sizeof(struct gen3_clk_priv), + .ops = &gen3_clk_ops, + .probe = gen3_clk_probe, + .remove = gen3_clk_remove, +}; |