diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 18:09:11 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 18:09:11 +0100 |
| commit | 67d986a0818cedeae3b818906059cfae55900f00 (patch) | |
| tree | 504f7c39307d92491c3a09472184c692adebed20 | |
| parent | 178636b2f2b6f8ed97733c28f99de2ea79b5bb6c (diff) | |
| parent | 5f7092aabf492fbc95a4cba1cc6c0d64c62a9abb (diff) | |
| download | linux-next-history-67d986a0818cedeae3b818906059cfae55900f00.tar.gz | |
Merge branch 'clk-next' of https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
27 files changed, 947 insertions, 169 deletions
diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml b/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml index 6f3a8578fe2a6..0db5504013d5e 100644 --- a/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml +++ b/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml @@ -37,6 +37,9 @@ properties: '#power-domain-cells': const: 1 + '#reset-cells': + const: 1 + required: - compatible - reg @@ -44,16 +47,27 @@ required: additionalProperties: false -if: - not: - properties: - compatible: - contains: - const: marvell,pxa1908-apmu - -then: - properties: - '#power-domain-cells': false +allOf: + - if: + not: + properties: + compatible: + contains: + const: marvell,pxa1908-apmu + then: + properties: + '#power-domain-cells': false + - if: + not: + properties: + compatible: + contains: + enum: + - marvell,pxa1908-apbc + - marvell,pxa1908-apbcp + then: + properties: + '#reset-cells': false examples: # APMU block: diff --git a/drivers/clk/bcm/clk-iproc-asiu.c b/drivers/clk/bcm/clk-iproc-asiu.c index 819ab1b55df3b..56a8132279814 100644 --- a/drivers/clk/bcm/clk-iproc-asiu.c +++ b/drivers/clk/bcm/clk-iproc-asiu.c @@ -27,8 +27,7 @@ struct iproc_asiu { void __iomem *div_base; void __iomem *gate_base; - struct clk_hw_onecell_data *clk_data; - struct iproc_asiu_clk *clks; + struct iproc_asiu_clk clks[]; }; #define to_asiu_clk(hw) container_of(hw, struct iproc_asiu_clk, hw) @@ -184,22 +183,19 @@ void __init iproc_asiu_setup(struct device_node *node, { int i, ret; struct iproc_asiu *asiu; + struct clk_hw_onecell_data *clk_data; if (WARN_ON(!gate || !div)) return; - asiu = kzalloc_obj(*asiu); + asiu = kzalloc_flex(*asiu, clks, num_clks); if (WARN_ON(!asiu)) return; - asiu->clk_data = kzalloc_flex(*asiu->clk_data, hws, num_clks); - if (WARN_ON(!asiu->clk_data)) + clk_data = kzalloc_flex(*clk_data, hws, num_clks); + if (WARN_ON(!clk_data)) goto err_clks; - asiu->clk_data->num = num_clks; - - asiu->clks = kzalloc_objs(*asiu->clks, num_clks); - if (WARN_ON(!asiu->clks)) - goto err_asiu_clks; + clk_data->num = num_clks; asiu->div_base = of_iomap(node, 0); if (WARN_ON(!asiu->div_base)) @@ -236,11 +232,11 @@ void __init iproc_asiu_setup(struct device_node *node, ret = clk_hw_register(NULL, &asiu_clk->hw); if (WARN_ON(ret)) goto err_clk_register; - asiu->clk_data->hws[i] = &asiu_clk->hw; + clk_data->hws[i] = &asiu_clk->hw; } ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, - asiu->clk_data); + clk_data); if (WARN_ON(ret)) goto err_clk_register; @@ -248,17 +244,14 @@ void __init iproc_asiu_setup(struct device_node *node, err_clk_register: while (--i >= 0) - clk_hw_unregister(asiu->clk_data->hws[i]); + clk_hw_unregister(clk_data->hws[i]); iounmap(asiu->gate_base); err_iomap_gate: iounmap(asiu->div_base); err_iomap_div: - kfree(asiu->clks); - -err_asiu_clks: - kfree(asiu->clk_data); + kfree(clk_data); err_clks: kfree(asiu); diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index fa5ccef73e60d..26f76a6db8202 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -521,7 +521,7 @@ static int axi_clkgen_setup_limits(struct axi_clkgen *axi_clkgen, axi_clkgen->limits.fvco_max = 1200000; axi_clkgen->limits.fpfd_max = 450000; break; - case ADI_AXI_FPGA_SPEED_2 ... ADI_AXI_FPGA_SPEED_2LV: + case ADI_AXI_FPGA_SPEED_2 ... ADI_AXI_FPGA_SPEED_2MP: axi_clkgen->limits.fvco_max = 1440000; axi_clkgen->limits.fpfd_max = 500000; if (family == ADI_AXI_FPGA_FAMILY_KINTEX || family == ADI_AXI_FPGA_FAMILY_ARTIX) { @@ -546,6 +546,9 @@ static int axi_clkgen_setup_limits(struct axi_clkgen *axi_clkgen, if (tech == ADI_AXI_FPGA_TECH_ULTRASCALE_PLUS) { axi_clkgen->limits.fvco_max = 1600000; axi_clkgen->limits.fvco_min = 800000; + } else if (tech == ADI_AXI_FPGA_TECH_VERSAL) { + axi_clkgen->limits.fvco_max = 4320000; + axi_clkgen->limits.fvco_min = 2160000; } return 0; diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c index d85dae4bdf895..acd9dff300722 100644 --- a/drivers/clk/clk-bulk.c +++ b/drivers/clk/clk-bulk.c @@ -12,7 +12,8 @@ #include <linux/of.h> #include <linux/slab.h> -static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks, +static int __must_check of_clk_bulk_get(struct device *dev, + struct device_node *np, int num_clks, struct clk_bulk_data *clks) { int ret; @@ -28,8 +29,8 @@ static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks, clks[i].clk = of_clk_get(np, i); if (IS_ERR(clks[i].clk)) { ret = PTR_ERR(clks[i].clk); - pr_err("%pOF: Failed to get clk index: %d ret: %d\n", - np, i, ret); + dev_err_probe(dev, ret, "%pOF: Failed to get clk index: %d (%s)\n", + np, i, clks[i].id); clks[i].clk = NULL; goto err; } @@ -43,7 +44,8 @@ err: return ret; } -static int __must_check of_clk_bulk_get_all(struct device_node *np, +static int __must_check of_clk_bulk_get_all(struct device *dev, + struct device_node *np, struct clk_bulk_data **clks) { struct clk_bulk_data *clk_bulk; @@ -58,7 +60,7 @@ static int __must_check of_clk_bulk_get_all(struct device_node *np, if (!clk_bulk) return -ENOMEM; - ret = of_clk_bulk_get(np, num_clks, clk_bulk); + ret = of_clk_bulk_get(dev, np, num_clks, clk_bulk); if (ret) { kfree(clk_bulk); return ret; @@ -144,7 +146,7 @@ int __must_check clk_bulk_get_all(struct device *dev, if (!np) return 0; - return of_clk_bulk_get_all(np, clks); + return of_clk_bulk_get_all(dev, np, clks); } EXPORT_SYMBOL(clk_bulk_get_all); diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index 3727d54724500..9149ce4f702d5 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -47,8 +47,8 @@ struct max77686_clk_init_data { struct max77686_clk_driver_data { enum max77686_chip_name chip; - struct max77686_clk_init_data *max_clk_data; size_t num_clks; + struct max77686_clk_init_data max_clk_data[] __counted_by(num_clks); }; static const struct @@ -168,19 +168,7 @@ static int max77686_clk_probe(struct platform_device *pdev) struct regmap *regmap; int i, ret, num_clks; - drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); - if (!drv_data) - return -ENOMEM; - - regmap = dev_get_regmap(parent, NULL); - if (!regmap) { - dev_err(dev, "Failed to get rtc regmap\n"); - return -ENODEV; - } - - drv_data->chip = id->driver_data; - - switch (drv_data->chip) { + switch (id->driver_data) { case CHIP_MAX77686: num_clks = MAX77686_CLKS_NUM; hw_clks = max77686_hw_clks_info; @@ -201,13 +189,19 @@ static int max77686_clk_probe(struct platform_device *pdev) return -EINVAL; } - drv_data->num_clks = num_clks; - drv_data->max_clk_data = devm_kcalloc(dev, num_clks, - sizeof(*drv_data->max_clk_data), - GFP_KERNEL); - if (!drv_data->max_clk_data) + drv_data = devm_kzalloc(dev, struct_size(drv_data, max_clk_data, num_clks), GFP_KERNEL); + if (!drv_data) return -ENOMEM; + drv_data->num_clks = num_clks; + drv_data->chip = id->driver_data; + + regmap = dev_get_regmap(parent, NULL); + if (!regmap) { + dev_err(dev, "Failed to get rtc regmap\n"); + return -ENODEV; + } + for (i = 0; i < num_clks; i++) { struct max77686_clk_init_data *max_clk_data; const char *clk_name; diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index fae65127cd4aa..08050ff1c8cf9 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -70,7 +70,7 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np, clk_data = kzalloc_obj(*clk_data); if (!clk_data) - goto err; + goto err_base; clk_data->base = base; clk_table = kzalloc_objs(*clk_table, nr_clks); @@ -83,6 +83,8 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np, return clk_data; err_data: kfree(clk_data); +err_base: + iounmap(base); err: return NULL; } diff --git a/drivers/clk/hisilicon/clkdivider-hi6220.c b/drivers/clk/hisilicon/clkdivider-hi6220.c index 1787ecefe601b..20a337383a1e1 100644 --- a/drivers/clk/hisilicon/clkdivider-hi6220.c +++ b/drivers/clk/hisilicon/clkdivider-hi6220.c @@ -26,8 +26,8 @@ * @shift: shift to the divider bit field * @width: width of the divider bit field * @mask: mask for setting divider rate - * @table: the div table that the divider supports * @lock: register lock + * @table: the div table that the divider supports */ struct hi6220_clk_divider { struct clk_hw hw; @@ -35,8 +35,8 @@ struct hi6220_clk_divider { u8 shift; u8 width; u32 mask; - const struct clk_div_table *table; spinlock_t *lock; + struct clk_div_table table[]; }; #define to_hi6220_clk_divider(_hw) \ @@ -108,24 +108,19 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, u32 max_div, min_div; int i; - /* allocate the divider */ - div = kzalloc_obj(*div); - if (!div) - return ERR_PTR(-ENOMEM); - /* Init the divider table */ max_div = div_mask(width) + 1; min_div = 1; - table = kzalloc_objs(*table, max_div + 1); - if (!table) { - kfree(div); + /* allocate the divider */ + div = kzalloc_flex(*div, table, max_div + 1); + if (!div) return ERR_PTR(-ENOMEM); - } for (i = 0; i < max_div; i++) { - table[i].div = min_div + i; - table[i].val = table[i].div - 1; + table = &div->table[i]; + table->div = min_div + i; + table->val = table->div - 1; } init.name = name; @@ -141,14 +136,11 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, div->mask = mask_bit ? BIT(mask_bit) : 0; div->lock = lock; div->hw.init = &init; - div->table = table; /* register the clock */ clk = clk_register(dev, &div->hw); - if (IS_ERR(clk)) { - kfree(table); + if (IS_ERR(clk)) kfree(div); - } return clk; } diff --git a/drivers/clk/mediatek/clk-mt7988-infracfg.c b/drivers/clk/mediatek/clk-mt7988-infracfg.c index ef8267319d91b..13ffa9d88e24b 100644 --- a/drivers/clk/mediatek/clk-mt7988-infracfg.c +++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c @@ -56,49 +56,45 @@ static const char *const infra_pcie_gfmux_tl_ck_o_p3_parents[] __initconst = { static const struct mtk_mux infra_muxes[] = { /* MODULE_CLK_SEL_0 */ - MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART0_SEL, "infra_mux_uart0_sel", - infra_mux_uart0_parents, 0x0018, 0x0010, 0x0014, 0, 1, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART1_SEL, "infra_mux_uart1_sel", - infra_mux_uart1_parents, 0x0018, 0x0010, 0x0014, 1, 1, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART2_SEL, "infra_mux_uart2_sel", - infra_mux_uart2_parents, 0x0018, 0x0010, 0x0014, 2, 1, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI0_SEL, "infra_mux_spi0_sel", infra_mux_spi0_parents, - 0x0018, 0x0010, 0x0014, 4, 1, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI1_SEL, "infra_mux_spi1_sel", infra_mux_spi1_parents, - 0x0018, 0x0010, 0x0014, 5, 1, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI2_SEL, "infra_mux_spi2_sel", infra_mux_spi0_parents, - 0x0018, 0x0010, 0x0014, 6, 1, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_SEL, "infra_pwm_sel", infra_pwm_bck_parents, 0x0018, - 0x0010, 0x0014, 14, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK1_SEL, "infra_pwm_ck1_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 16, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK2_SEL, "infra_pwm_ck2_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 18, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK3_SEL, "infra_pwm_ck3_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 20, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK4_SEL, "infra_pwm_ck4_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 22, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK5_SEL, "infra_pwm_ck5_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 24, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK6_SEL, "infra_pwm_ck6_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 26, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK7_SEL, "infra_pwm_ck7_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 28, 2, -1, -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK8_SEL, "infra_pwm_ck8_sel", infra_pwm_bck_parents, - 0x0018, 0x0010, 0x0014, 30, 2, -1, -1, -1), + MUX_CLR_SET(CLK_INFRA_MUX_UART0_SEL, "infra_mux_uart0_sel", + infra_mux_uart0_parents, 0x0018, 0x0010, 0x0014, 0, 1), + MUX_CLR_SET(CLK_INFRA_MUX_UART1_SEL, "infra_mux_uart1_sel", + infra_mux_uart1_parents, 0x0018, 0x0010, 0x0014, 1, 1), + MUX_CLR_SET(CLK_INFRA_MUX_UART2_SEL, "infra_mux_uart2_sel", + infra_mux_uart2_parents, 0x0018, 0x0010, 0x0014, 2, 1), + MUX_CLR_SET(CLK_INFRA_MUX_SPI0_SEL, "infra_mux_spi0_sel", + infra_mux_spi0_parents, 0x0018, 0x0010, 0x0014, 4, 1), + MUX_CLR_SET(CLK_INFRA_MUX_SPI1_SEL, "infra_mux_spi1_sel", + infra_mux_spi1_parents, 0x0018, 0x0010, 0x0014, 5, 1), + MUX_CLR_SET(CLK_INFRA_MUX_SPI2_SEL, "infra_mux_spi2_sel", + infra_mux_spi0_parents, 0x0018, 0x0010, 0x0014, 6, 1), + MUX_CLR_SET(CLK_INFRA_PWM_SEL, "infra_pwm_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 14, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK1_SEL, "infra_pwm_ck1_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 16, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK2_SEL, "infra_pwm_ck2_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 18, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK3_SEL, "infra_pwm_ck3_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 20, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK4_SEL, "infra_pwm_ck4_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 22, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK5_SEL, "infra_pwm_ck5_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 24, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK6_SEL, "infra_pwm_ck6_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 26, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK7_SEL, "infra_pwm_ck7_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 28, 2), + MUX_CLR_SET(CLK_INFRA_PWM_CK8_SEL, "infra_pwm_ck8_sel", + infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 30, 2), /* MODULE_CLK_SEL_1 */ - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL, "infra_pcie_gfmux_tl_o_p0_sel", - infra_pcie_gfmux_tl_ck_o_p0_parents, 0x0028, 0x0020, 0x0024, 0, 2, -1, - -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL, "infra_pcie_gfmux_tl_o_p1_sel", - infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0028, 0x0020, 0x0024, 2, 2, -1, - -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL, "infra_pcie_gfmux_tl_o_p2_sel", - infra_pcie_gfmux_tl_ck_o_p2_parents, 0x0028, 0x0020, 0x0024, 4, 2, -1, - -1, -1), - MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL, "infra_pcie_gfmux_tl_o_p3_sel", - infra_pcie_gfmux_tl_ck_o_p3_parents, 0x0028, 0x0020, 0x0024, 6, 2, -1, - -1, -1), + MUX_CLR_SET(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL, "infra_pcie_gfmux_tl_o_p0_sel", + infra_pcie_gfmux_tl_ck_o_p0_parents, 0x0028, 0x0020, 0x0024, 0, 2), + MUX_CLR_SET(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL, "infra_pcie_gfmux_tl_o_p1_sel", + infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0028, 0x0020, 0x0024, 2, 2), + MUX_CLR_SET(CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL, "infra_pcie_gfmux_tl_o_p2_sel", + infra_pcie_gfmux_tl_ck_o_p2_parents, 0x0028, 0x0020, 0x0024, 4, 2), + MUX_CLR_SET(CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL, "infra_pcie_gfmux_tl_o_p3_sel", + infra_pcie_gfmux_tl_ck_o_p3_parents, 0x0028, 0x0020, 0x0024, 6, 2), }; static const struct mtk_gate_regs infra0_cg_regs = { diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c index 50b43807c60cf..12c8890d922fe 100644 --- a/drivers/clk/mediatek/clk-mt8192.c +++ b/drivers/clk/mediatek/clk-mt8192.c @@ -579,8 +579,8 @@ static const struct mtk_mux top_mtk_muxes[] = { dsp7_parents, 0x050, 0x054, 0x058, 0, 3, 7, 0x004, 16), MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_REF_SEL, "mfg_ref_sel", mfg_ref_parents, 0x050, 0x054, 0x058, 16, 2, 23, 0x004, 18), - MUX_CLR_SET_UPD(CLK_TOP_MFG_PLL_SEL, "mfg_pll_sel", - mfg_pll_parents, 0x050, 0x054, 0x058, 18, 1, -1, -1), + MUX_CLR_SET(CLK_TOP_MFG_PLL_SEL, "mfg_pll_sel", mfg_pll_parents, + 0x050, 0x054, 0x058, 18, 1), MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x050, 0x054, 0x058, 24, 3, 31, 0x004, 19), /* CLK_CFG_5 */ diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h index 151e56dcf8842..1a9baf306b4a7 100644 --- a/drivers/clk/mediatek/clk-mux.h +++ b/drivers/clk/mediatek/clk-mux.h @@ -126,6 +126,11 @@ extern const struct clk_ops mtk_mux_gate_hwv_fenc_clr_set_upd_ops; 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ mtk_mux_clr_set_upd_ops) +#define MUX_CLR_SET(_id, _name, _parents, _mux_ofs, \ + _mux_set_ofs, _mux_clr_ofs, _shift, _width) \ + MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ + _mux_set_ofs, _mux_clr_ofs, _shift, _width, 0, -1) + #define MUX_GATE_HWV_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ diff --git a/drivers/clk/mmp/clk-pxa1908-apbc.c b/drivers/clk/mmp/clk-pxa1908-apbc.c index 3fd7b5e644f3b..438ece4f047dc 100644 --- a/drivers/clk/mmp/clk-pxa1908-apbc.c +++ b/drivers/clk/mmp/clk-pxa1908-apbc.c @@ -7,6 +7,7 @@ #include <dt-bindings/clock/marvell,pxa1908.h> #include "clk.h" +#include "reset.h" #define APBC_UART0 0x0 #define APBC_UART1 0x4 @@ -44,22 +45,25 @@ static const char * const uart_parent_names[] = {"pll1_117", "uart_pll"}; static const char * const ssp_parent_names[] = {"pll1_d16", "pll1_d48", "pll1_d24", "pll1_d12"}; static struct mmp_param_gate_clk apbc_gate_clks[] = { - {PXA1908_CLK_TWSI0, "twsi0_clk", "pll1_32", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_TWSI1, "twsi1_clk", "pll1_32", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_TWSI3, "twsi3_clk", "pll1_32", CLK_SET_RATE_PARENT, APBC_TWSI3, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x7, 3, 0, MMP_CLK_GATE_NEED_DELAY, NULL}, - {PXA1908_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x87, 0x83, 0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA1908_CLK_TWSI0, "twsi0_clk", "pll1_32", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_TWSI1, "twsi1_clk", "pll1_32", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_TWSI3, "twsi3_clk", "pll1_32", CLK_SET_RATE_PARENT, APBC_TWSI3, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 3, 0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA1908_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA1908_CLK_PWM1, "pwm1_clk", "pwm01_apb_share", CLK_SET_RATE_PARENT, APBC_PWM1, 0x2, 2, 0, 0, NULL}, + {PXA1908_CLK_PWM3, "pwm3_clk", "pwm23_apb_share", CLK_SET_RATE_PARENT, APBC_PWM3, 0x2, 2, 0, 0, NULL}, + {PXA1908_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 3, 0, 0, &uart0_lock}, + {PXA1908_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 3, 0, 0, &uart1_lock}, + {PXA1908_CLK_THERMAL, "thermal_clk", NULL, 0, APBC_THERMAL, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_IPC_RST, "ipc_clk", NULL, 0, APBC_IPC_RST, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_SSP0, "ssp0_clk", "ssp0_mux", 0, APBC_SSP0, 0x3, 3, 0, 0, NULL}, + {PXA1908_CLK_SSP2, "ssp2_clk", "ssp2_mux", 0, APBC_SSP2, 0x3, 3, 0, 0, NULL}, +}; + +static struct mmp_param_gate_clk apbc_gate_no_reset_clks[] = { {PXA1908_CLK_PWM0, "pwm0_clk", "pwm01_apb_share", CLK_SET_RATE_PARENT, APBC_PWM0, 0x2, 2, 0, 0, &pwm0_lock}, - {PXA1908_CLK_PWM1, "pwm1_clk", "pwm01_apb_share", CLK_SET_RATE_PARENT, APBC_PWM1, 0x6, 2, 0, 0, NULL}, {PXA1908_CLK_PWM2, "pwm2_clk", "pwm23_apb_share", CLK_SET_RATE_PARENT, APBC_PWM2, 0x2, 2, 0, 0, NULL}, - {PXA1908_CLK_PWM3, "pwm3_clk", "pwm23_apb_share", CLK_SET_RATE_PARENT, APBC_PWM3, 0x6, 2, 0, 0, NULL}, - {PXA1908_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x7, 3, 0, 0, &uart0_lock}, - {PXA1908_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x7, 3, 0, 0, &uart1_lock}, - {PXA1908_CLK_THERMAL, "thermal_clk", NULL, 0, APBC_THERMAL, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_IPC_RST, "ipc_clk", NULL, 0, APBC_IPC_RST, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_SSP0, "ssp0_clk", "ssp0_mux", 0, APBC_SSP0, 0x7, 3, 0, 0, NULL}, - {PXA1908_CLK_SSP2, "ssp2_clk", "ssp2_mux", 0, APBC_SSP2, 0x7, 3, 0, 0, NULL}, }; static struct mmp_param_mux_clk apbc_mux_clks[] = { @@ -89,6 +93,30 @@ static void pxa1908_apb_periph_clk_init(struct pxa1908_clk_unit *pxa_unit) ARRAY_SIZE(apbc_mux_clks)); mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->base, ARRAY_SIZE(apbc_gate_clks)); + mmp_register_gate_clks(unit, apbc_gate_no_reset_clks, pxa_unit->base, + ARRAY_SIZE(apbc_gate_no_reset_clks)); +} + +/* Taken from clk-of-pxa1928.c */ +static void pxa1908_clk_reset_init(struct device_node *np, + struct pxa1908_clk_unit *pxa_unit) +{ + struct mmp_clk_reset_cell *cells; + int nr_cells = ARRAY_SIZE(apbc_gate_clks); + + cells = kzalloc_objs(*cells, nr_cells); + if (!cells) + return; + + for (int i = 0; i < nr_cells; i++) { + cells[i].clk_id = apbc_gate_clks[i].id; + cells[i].reg = pxa_unit->base + apbc_gate_clks[i].offset; + cells[i].bits = BIT(2); + cells[i].flags = 0; + cells[i].lock = apbc_gate_clks[i].lock; + }; + + mmp_clk_reset_register(np, cells, nr_cells); } static int pxa1908_apbc_probe(struct platform_device *pdev) @@ -107,6 +135,8 @@ static int pxa1908_apbc_probe(struct platform_device *pdev) pxa1908_apb_periph_clk_init(pxa_unit); + pxa1908_clk_reset_init(pdev->dev.of_node, pxa_unit); + return 0; } diff --git a/drivers/clk/mmp/clk-pxa1908-apbcp.c b/drivers/clk/mmp/clk-pxa1908-apbcp.c index f638d7e89b472..1aa476103553e 100644 --- a/drivers/clk/mmp/clk-pxa1908-apbcp.c +++ b/drivers/clk/mmp/clk-pxa1908-apbcp.c @@ -7,6 +7,7 @@ #include <dt-bindings/clock/marvell,pxa1908.h> #include "clk.h" +#include "reset.h" #define APBCP_UART2 0x1c #define APBCP_TWSI2 0x28 @@ -24,9 +25,9 @@ static DEFINE_SPINLOCK(uart2_lock); static const char * const uart_parent_names[] = {"pll1_117", "uart_pll"}; static struct mmp_param_gate_clk apbcp_gate_clks[] = { - {PXA1908_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBCP_UART2, 0x7, 0x3, 0x0, 0, &uart2_lock}, - {PXA1908_CLK_TWSI2, "twsi2_clk", "pll1_32", CLK_SET_RATE_PARENT, APBCP_TWSI2, 0x7, 0x3, 0x0, 0, NULL}, - {PXA1908_CLK_AICER, "ripc_clk", NULL, 0, APBCP_AICER, 0x7, 0x2, 0x0, 0, NULL}, + {PXA1908_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBCP_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock}, + {PXA1908_CLK_TWSI2, "twsi2_clk", "pll1_32", CLK_SET_RATE_PARENT, APBCP_TWSI2, 0x3, 0x3, 0x0, 0, NULL}, + {PXA1908_CLK_AICER, "ripc_clk", NULL, 0, APBCP_AICER, 0x3, 0x2, 0x0, 0, NULL}, }; static struct mmp_param_mux_clk apbcp_mux_clks[] = { @@ -43,6 +44,28 @@ static void pxa1908_apb_p_periph_clk_init(struct pxa1908_clk_unit *pxa_unit) ARRAY_SIZE(apbcp_gate_clks)); } +/* Taken from clk-of-pxa1928.c */ +static void pxa1908_clk_reset_init(struct device_node *np, + struct pxa1908_clk_unit *pxa_unit) +{ + struct mmp_clk_reset_cell *cells; + int nr_cells = ARRAY_SIZE(apbcp_gate_clks); + + cells = kzalloc_objs(*cells, nr_cells); + if (!cells) + return; + + for (int i = 0; i < nr_cells; i++) { + cells[i].clk_id = apbcp_gate_clks[i].id; + cells[i].reg = pxa_unit->base + apbcp_gate_clks[i].offset; + cells[i].bits = BIT(2); + cells[i].flags = 0; + cells[i].lock = apbcp_gate_clks[i].lock; + }; + + mmp_clk_reset_register(np, cells, nr_cells); +} + static int pxa1908_apbcp_probe(struct platform_device *pdev) { struct pxa1908_clk_unit *pxa_unit; @@ -59,6 +82,8 @@ static int pxa1908_apbcp_probe(struct platform_device *pdev) pxa1908_apb_p_periph_clk_init(pxa_unit); + pxa1908_clk_reset_init(pdev->dev.of_node, pxa_unit); + return 0; } diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 28f2e1b2a9323..0f9ae5f5cefd2 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -189,10 +189,10 @@ DEFINE_SPINLOCK(ctrl_gating_lock); struct clk_gating_ctrl { spinlock_t *lock; - struct clk **gates; int num_gates; void __iomem *base; u32 saved_reg; + struct clk *gates[] __counted_by(num_gates); }; static struct clk_gating_ctrl *ctrl; @@ -257,24 +257,21 @@ void __init mvebu_clk_gating_setup(struct device_node *np, clk_put(clk); } - ctrl = kzalloc_obj(*ctrl); + /* Count, allocate, and register clock gates */ + for (n = 0; desc[n].name;) + n++; + + ctrl = kzalloc_flex(*ctrl, gates, n); if (WARN_ON(!ctrl)) goto ctrl_out; + ctrl->num_gates = n; + /* lock must already be initialized */ ctrl->lock = &ctrl_gating_lock; ctrl->base = base; - /* Count, allocate, and register clock gates */ - for (n = 0; desc[n].name;) - n++; - - ctrl->num_gates = n; - ctrl->gates = kzalloc_objs(*ctrl->gates, ctrl->num_gates); - if (WARN_ON(!ctrl->gates)) - goto gates_out; - for (n = 0; n < ctrl->num_gates; n++) { const char *parent = (desc[n].parent) ? desc[n].parent : default_parent; @@ -289,8 +286,6 @@ void __init mvebu_clk_gating_setup(struct device_node *np, register_syscore(&clk_gate_syscore); return; -gates_out: - kfree(ctrl); ctrl_out: iounmap(base); } diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index dcb6d0c0b41aa..3793e701835ff 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -27,8 +27,8 @@ #define CCU_BRANCH_HAVE_DIV2 BIT(1) struct lpc18xx_branch_clk_data { - const char **name; int num; + const char *name[] __counted_by(num); }; struct lpc18xx_clk_branch { @@ -266,6 +266,7 @@ static void __init lpc18xx_ccu_init(struct device_node *np) { struct lpc18xx_branch_clk_data *clk_data; void __iomem *reg_base; + size_t size; int i, ret; reg_base = of_iomap(np, 0); @@ -274,19 +275,14 @@ static void __init lpc18xx_ccu_init(struct device_node *np) return; } - clk_data = kzalloc_obj(*clk_data); + size = of_property_count_strings(np, "clock-names"); + clk_data = kzalloc_flex(*clk_data, name, size); if (!clk_data) { iounmap(reg_base); return; } - clk_data->num = of_property_count_strings(np, "clock-names"); - clk_data->name = kcalloc(clk_data->num, sizeof(char *), GFP_KERNEL); - if (!clk_data->name) { - iounmap(reg_base); - kfree(clk_data); - return; - } + clk_data->num = size; for (i = 0; i < clk_data->num; i++) { ret = of_property_read_string_index(np, "clock-names", i, diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c index 7f47644396e6c..1a2bbc5e92999 100644 --- a/drivers/clk/renesas/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -42,6 +42,8 @@ static struct div4_clk div4_clks[] = { { "b", CPG_FRQCRA, 8 }, { "m1", CPG_FRQCRA, 4 }, { "m2", CPG_FRQCRA, 0 }, + { "ztr", CPG_FRQCRB, 20 }, + { "zt", CPG_FRQCRB, 16 }, { "zx", CPG_FRQCRB, 12 }, { "zs", CPG_FRQCRB, 8 }, { "hp", CPG_FRQCRB, 4 }, diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index 635d59ead499e..31a79674583e8 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -37,6 +37,8 @@ static struct div4_clk div4_clks[] = { { "zg", CPG_FRQCRA, 16 }, { "b", CPG_FRQCRA, 8 }, { "m1", CPG_FRQCRA, 4 }, + { "ztr", CPG_FRQCRB, 20 }, + { "zt", CPG_FRQCRB, 16 }, { "hp", CPG_FRQCRB, 4 }, { "hpp", CPG_FRQCRC, 20 }, { "usbp", CPG_FRQCRC, 16 }, diff --git a/drivers/clk/renesas/r9a08g046-cpg.c b/drivers/clk/renesas/r9a08g046-cpg.c index 6759957980f22..fc9db5a2f0ac6 100644 --- a/drivers/clk/renesas/r9a08g046-cpg.c +++ b/drivers/clk/renesas/r9a08g046-cpg.c @@ -17,17 +17,72 @@ /* RZ/G3L Specific registers. */ #define G3L_CPG_PL2_DDIV (0x204) #define G3L_CPG_PL3_DDIV (0x208) +#define G3L_CPG_CA55CORE_DDIV (0x234) +#define G3L_CPG_RSCI_DDIV (0x238) +#define G3L_CPG_RSPI_DDIV (0x23c) #define G3L_CLKDIVSTATUS (0x280) +#define G3L_CPG_ETH_SSEL (0x410) +#define G3L_CPG_RSCI_SSEL (0x414) +#define G3L_CPG_RSPI_SSEL (0x418) +#define G3L_CPG_ETH_SDIV (0x434) /* RZ/G3L Specific division configuration. */ #define G3L_DIVPL2A DDIV_PACK(G3L_CPG_PL2_DDIV, 0, 2) #define G3L_DIVPL2B DDIV_PACK(G3L_CPG_PL2_DDIV, 4, 2) #define G3L_DIVPL3A DDIV_PACK(G3L_CPG_PL3_DDIV, 0, 2) +#define G3L_DIV_CA55_CORE0 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 0, 3) +#define G3L_DIV_CA55_CORE1 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 4, 3) +#define G3L_DIV_CA55_CORE2 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 8, 3) +#define G3L_DIV_CA55_CORE3 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 12, 3) +#define G3L_DIV_RSCI0 DDIV_PACK(G3L_CPG_RSCI_DDIV, 0, 2) +#define G3L_DIV_RSCI1 DDIV_PACK(G3L_CPG_RSCI_DDIV, 2, 2) +#define G3L_DIV_RSCI2 DDIV_PACK(G3L_CPG_RSCI_DDIV, 4, 2) +#define G3L_DIV_RSCI3 DDIV_PACK(G3L_CPG_RSCI_DDIV, 6, 2) +#define G3L_DIV_RSPI0 DDIV_PACK(G3L_CPG_RSPI_DDIV, 0, 2) +#define G3L_DIV_RSPI1 DDIV_PACK(G3L_CPG_RSPI_DDIV, 2, 2) +#define G3L_DIV_RSPI2 DDIV_PACK(G3L_CPG_RSPI_DDIV, 4, 2) +#define G3L_SDIV_ETH_A DDIV_PACK(G3L_CPG_ETH_SDIV, 0, 2) +#define G3L_SDIV_ETH_B DDIV_PACK(G3L_CPG_ETH_SDIV, 4, 1) +#define G3L_SDIV_ETH_C DDIV_PACK(G3L_CPG_ETH_SDIV, 8, 2) +#define G3L_SDIV_ETH_D DDIV_PACK(G3L_CPG_ETH_SDIV, 12, 1) /* RZ/G3L Clock status configuration. */ #define G3L_DIVPL2A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 4, 1) #define G3L_DIVPL2B_STS DDIV_PACK(G3L_CLKDIVSTATUS, 5, 1) #define G3L_DIVPL3A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 8, 1) +#define G3L_DIV_CA55_CORE0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 12, 1) +#define G3L_DIV_CA55_CORE1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 13, 1) +#define G3L_DIV_CA55_CORE2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 14, 1) +#define G3L_DIV_CA55_CORE3_STS DDIV_PACK(G3L_CLKDIVSTATUS, 15, 1) +#define G3L_DIV_RSCI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 16, 1) +#define G3L_DIV_RSCI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 17, 1) +#define G3L_DIV_RSCI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 18, 1) +#define G3L_DIV_RSCI3_STS DDIV_PACK(G3L_CLKDIVSTATUS, 19, 1) +#define G3L_DIV_RSPI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 20, 1) +#define G3L_DIV_RSPI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 21, 1) +#define G3L_DIV_RSPI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 22, 1) + +/* RZ/G3L Specific clocks select. */ +#define G3L_SEL_ETH0_TX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 0, 1) +#define G3L_SEL_ETH0_RX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 1, 1) +#define G3L_SEL_ETH0_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 2, 1) +#define G3L_SEL_ETH0_CLK_TX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 3, 1) +#define G3L_SEL_ETH0_CLK_RX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 4, 1) +#define G3L_SEL_ETH1_TX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 8, 1) +#define G3L_SEL_ETH1_RX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 9, 1) +#define G3L_SEL_ETH1_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 10, 1) +#define G3L_SEL_ETH1_CLK_TX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 11, 1) +#define G3L_SEL_ETH1_CLK_RX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 12, 1) +#define G3L_SEL_RSCI0 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 0, 2) +#define G3L_SEL_RSCI1 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 2, 2) +#define G3L_SEL_RSCI2 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 4, 2) +#define G3L_SEL_RSCI3 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 6, 2) +#define G3L_SEL_RSPI0 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 0, 2) +#define G3L_SEL_RSPI1 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 2, 2) +#define G3L_SEL_RSPI2 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 4, 2) + +/* PLL 1/4/6/7 configuration registers macro. */ +#define G3L_PLL1467_CONF(clk1, clk2, setting) ((clk1) << 22 | (clk2) << 12 | (setting)) enum clk_ids { /* Core Clock Outputs exported to DT */ @@ -41,16 +96,72 @@ enum clk_ids { CLK_ETH1_RXC_RX_CLK_IN, /* Internal Core Clocks */ + CLK_PLL1, CLK_PLL2, CLK_PLL2_DIV2, + CLK_PLL2_DIV2_4, + CLK_PLL2_DIV5, + CLK_PLL2_DIV6, + CLK_PLL2_DIV7, CLK_PLL3, CLK_PLL3_DIV2, + CLK_PLL6, + CLK_PLL6_DIV10, + CLK_SEL_ETH0_TX, + CLK_SEL_ETH0_RX, + CLK_SEL_ETH0_RM, + CLK_SEL_ETH1_TX, + CLK_SEL_ETH1_RX, + CLK_SEL_ETH1_RM, + CLK_SEL_RSCI0, + CLK_SEL_RSCI1, + CLK_SEL_RSCI2, + CLK_SEL_RSCI3, + CLK_SEL_RSPI0, + CLK_SEL_RSPI1, + CLK_SEL_RSPI2, + CLK_ETH0_TR, + CLK_ETH0_RM, + CLK_ETH1_TR, + CLK_ETH1_RM, /* Module Clocks */ MOD_CLK_BASE, }; /* Divider tables */ +static const struct clk_div_table dtable_1_8[] = { + { 0, 1 }, + { 1, 2 }, + { 2, 4 }, + { 3, 8 }, + { 0, 0 }, +}; + +static const struct clk_div_table dtable_1_32[] = { + { 0, 1 }, + { 1, 2 }, + { 2, 4 }, + { 3, 8 }, + { 4, 16 }, + { 5, 32 }, + { 0, 0 }, +}; + +static const struct clk_div_table dtable_2_20[] = { + { 0, 2 }, + { 1, 20 }, + { 0, 0 }, +}; + +static const struct clk_div_table dtable_2_16[] = { + { 0, 2 }, + { 1, 4 }, + { 2, 8 }, + { 3, 16 }, + { 0, 0 }, +}; + static const struct clk_div_table dtable_4_128[] = { { 0, 4 }, { 1, 8 }, @@ -59,6 +170,13 @@ static const struct clk_div_table dtable_4_128[] = { { 0, 0 }, }; +static const struct clk_div_table dtable_4_200[] = { + { 0, 4 }, + { 1, 20 }, + { 2, 200 }, + { 0, 0 }, +}; + static const struct clk_div_table dtable_8_256[] = { { 0, 8 }, { 1, 16 }, @@ -67,6 +185,19 @@ static const struct clk_div_table dtable_8_256[] = { { 0, 0 }, }; +/* Mux clock names tables. */ +static const char * const sel_eth0_tx[] = { ".div_eth0_tr", "eth0_txc_tx_clk" }; +static const char * const sel_eth0_rx[] = { ".div_eth0_tr", "eth0_rxc_rx_clk" }; +static const char * const sel_eth0_rm[] = { ".pll6_div10", "eth0_rxc_rx_clk" }; +static const char * const sel_eth1_tx[] = { ".div_eth1_tr", "eth1_txc_tx_clk" }; +static const char * const sel_eth1_rx[] = { ".div_eth1_tr", "eth1_rxc_rx_clk" }; +static const char * const sel_eth1_rm[] = { ".pll6_div10", "eth1_rxc_rx_clk" }; +static const char * const sel_rsci_rspi[] = { ".pll2_div5", ".pll2_div6", ".pll2_div7", ".pll2_div2_4" }; +static const char * const sel_eth0_clk_tx_i[] = { ".sel_eth0_tx", ".div_eth0_rm" }; +static const char * const sel_eth0_clk_rx_i[] = { ".sel_eth0_rx", ".div_eth0_rm" }; +static const char * const sel_eth1_clk_tx_i[] = { ".sel_eth1_tx", ".div_eth1_rm" }; +static const char * const sel_eth1_clk_rx_i[] = { ".sel_eth1_rx", ".div_eth1_rm" }; + static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), @@ -76,18 +207,82 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { DEF_INPUT("eth1_rxc_rx_clk", CLK_ETH1_RXC_RX_CLK_IN), /* Internal Core Clocks */ + DEF_G3L_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3L_PLL1467_CONF(0x4, 0x8, 0x100), + 1200000000UL), DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3), DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3), + DEF_G3L_PLL(".pll6", CLK_PLL6, CLK_EXTAL, G3L_PLL1467_CONF(0x54, 0x58, 0), + 500000000UL), DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2), + DEF_FIXED(".pll2_div2_4", CLK_PLL2_DIV2_4, CLK_PLL2_DIV2, 1, 4), + DEF_FIXED(".pll2_div5", CLK_PLL2_DIV5, CLK_PLL2, 1, 5), + DEF_FIXED(".pll2_div6", CLK_PLL2_DIV6, CLK_PLL2, 1, 6), + DEF_FIXED(".pll2_div7", CLK_PLL2_DIV7, CLK_PLL2, 1, 7), DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2), + DEF_FIXED(".pll6_div10", CLK_PLL6_DIV10, CLK_PLL6, 1, 10), + DEF_MUX(".sel_rsci0", CLK_SEL_RSCI0, G3L_SEL_RSCI0, sel_rsci_rspi), + DEF_MUX(".sel_rsci1", CLK_SEL_RSCI1, G3L_SEL_RSCI1, sel_rsci_rspi), + DEF_MUX(".sel_rsci2", CLK_SEL_RSCI2, G3L_SEL_RSCI2, sel_rsci_rspi), + DEF_MUX(".sel_rsci3", CLK_SEL_RSCI3, G3L_SEL_RSCI3, sel_rsci_rspi), + DEF_MUX(".sel_rspi0", CLK_SEL_RSPI0, G3L_SEL_RSPI0, sel_rsci_rspi), + DEF_MUX(".sel_rspi1", CLK_SEL_RSPI1, G3L_SEL_RSPI1, sel_rsci_rspi), + DEF_MUX(".sel_rspi2", CLK_SEL_RSPI2, G3L_SEL_RSPI2, sel_rsci_rspi), + DEF_MUX(".sel_eth0_tx", CLK_SEL_ETH0_TX, G3L_SEL_ETH0_TX, sel_eth0_tx), + DEF_MUX(".sel_eth0_rx", CLK_SEL_ETH0_RX, G3L_SEL_ETH0_RX, sel_eth0_rx), + DEF_MUX(".sel_eth0_rm", CLK_SEL_ETH0_RM, G3L_SEL_ETH0_RM, sel_eth0_rm), + DEF_MUX(".sel_eth1_tx", CLK_SEL_ETH1_TX, G3L_SEL_ETH1_TX, sel_eth1_tx), + DEF_MUX(".sel_eth1_rx", CLK_SEL_ETH1_RX, G3L_SEL_ETH1_RX, sel_eth1_rx), + DEF_MUX(".sel_eth1_rm", CLK_SEL_ETH1_RM, G3L_SEL_ETH1_RM, sel_eth1_rm), + DEF_DIV(".div_eth0_tr", CLK_ETH0_TR, CLK_PLL6, G3L_SDIV_ETH_A, dtable_4_200), + DEF_DIV(".div_eth1_tr", CLK_ETH1_TR, CLK_PLL6, G3L_SDIV_ETH_C, dtable_4_200), + DEF_DIV(".div_eth0_rm", CLK_ETH0_RM, CLK_SEL_ETH0_RM, G3L_SDIV_ETH_B, dtable_2_20), + DEF_DIV(".div_eth1_rm", CLK_ETH1_RM, CLK_SEL_ETH1_RM, G3L_SDIV_ETH_D, dtable_2_20), /* Core output clk */ + DEF_G3S_DIV("IC0", R9A08G046_CLK_IC0, CLK_PLL1, G3L_DIV_CA55_CORE0, G3L_DIV_CA55_CORE0_STS, + dtable_1_32, 0, 0, 0, NULL), + DEF_G3S_DIV("IC1", R9A08G046_CLK_IC1, CLK_PLL1, G3L_DIV_CA55_CORE1, G3L_DIV_CA55_CORE1_STS, + dtable_1_32, 0, 0, 0, NULL), + DEF_G3S_DIV("IC2", R9A08G046_CLK_IC2, CLK_PLL1, G3L_DIV_CA55_CORE2, G3L_DIV_CA55_CORE2_STS, + dtable_1_32, 0, 0, 0, NULL), + DEF_G3S_DIV("IC3", R9A08G046_CLK_IC3, CLK_PLL1, G3L_DIV_CA55_CORE3, G3L_DIV_CA55_CORE3_STS, + dtable_1_32, 0, 0, 0, NULL), DEF_G3S_DIV("P0", R9A08G046_CLK_P0, CLK_PLL2_DIV2, G3L_DIVPL2B, G3L_DIVPL2B_STS, dtable_8_256, 0, 0, 0, NULL), DEF_G3S_DIV("P1", R9A08G046_CLK_P1, CLK_PLL3_DIV2, G3L_DIVPL3A, G3L_DIVPL3A_STS, dtable_4_128, 0, 0, 0, NULL), DEF_G3S_DIV("P3", R9A08G046_CLK_P3, CLK_PLL2_DIV2, G3L_DIVPL2A, G3L_DIVPL2A_STS, dtable_4_128, 0, 0, 0, NULL), + DEF_G3S_DIV("P13", R9A08G046_CLK_P13, CLK_SEL_RSCI0, G3L_DIV_RSCI0, G3L_DIV_RSCI0_STS, + dtable_2_16, 0, 100000000UL, 0, NULL), + DEF_G3S_DIV("P14", R9A08G046_CLK_P14, CLK_SEL_RSCI1, G3L_DIV_RSCI1, G3L_DIV_RSCI1_STS, + dtable_2_16, 0, 100000000UL, 0, NULL), + DEF_G3S_DIV("P15", R9A08G046_CLK_P15, CLK_SEL_RSCI2, G3L_DIV_RSCI2, G3L_DIV_RSCI2_STS, + dtable_2_16, 0, 100000000UL, 0, NULL), + DEF_G3S_DIV("P16", R9A08G046_CLK_P16, CLK_SEL_RSCI3, G3L_DIV_RSCI3, G3L_DIV_RSCI3_STS, + dtable_2_16, 0, 100000000UL, 0, NULL), + DEF_G3S_DIV("P17", R9A08G046_CLK_P17, CLK_SEL_RSPI0, G3L_DIV_RSPI0, G3L_DIV_RSPI0_STS, + dtable_1_8, 0, 200000000UL, 0, NULL), + DEF_G3S_DIV("P18", R9A08G046_CLK_P18, CLK_SEL_RSPI1, G3L_DIV_RSPI1, G3L_DIV_RSPI1_STS, + dtable_1_8, 0, 200000000UL, 0, NULL), + DEF_G3S_DIV("P19", R9A08G046_CLK_P19, CLK_SEL_RSPI2, G3L_DIV_RSPI2, G3L_DIV_RSPI2_STS, + dtable_1_8, 0, 200000000UL, 0, NULL), + DEF_FIXED("HP", R9A08G046_CLK_HP, CLK_PLL6_DIV10, 1, 1), + DEF_MUX_FLAGS("ETHTX01", R9A08G046_CLK_ETHTX01, G3L_SEL_ETH0_CLK_TX_I, sel_eth0_clk_tx_i, + CLK_SET_RATE_PARENT), + DEF_MUX_FLAGS("ETHRX01", R9A08G046_CLK_ETHRX01, G3L_SEL_ETH0_CLK_RX_I, sel_eth0_clk_rx_i, + CLK_SET_RATE_PARENT), + DEF_MUX_FLAGS("ETHTX11", R9A08G046_CLK_ETHTX11, G3L_SEL_ETH1_CLK_TX_I, sel_eth1_clk_tx_i, + CLK_SET_RATE_PARENT), + DEF_MUX_FLAGS("ETHRX11", R9A08G046_CLK_ETHRX11, G3L_SEL_ETH1_CLK_RX_I, sel_eth1_clk_rx_i, + CLK_SET_RATE_PARENT), + DEF_FIXED("ETHRM0", R9A08G046_CLK_ETHRM0, CLK_SEL_ETH0_RM, 1, 1), + DEF_FIXED("ETHTX02", R9A08G046_CLK_ETHTX02, CLK_SEL_ETH0_TX, 1, 1), + DEF_FIXED("ETHRX02", R9A08G046_CLK_ETHRX02, CLK_SEL_ETH0_RX, 1, 1), + DEF_FIXED("ETHRM1", R9A08G046_CLK_ETHRM1, CLK_SEL_ETH1_RM, 1, 1), + DEF_FIXED("ETHTX12", R9A08G046_CLK_ETHTX12, CLK_SEL_ETH1_TX, 1, 1), + DEF_FIXED("ETHRX12", R9A08G046_CLK_ETHRX12, CLK_SEL_ETH1_RX, 1, 1), + DEF_FIXED("OSCCLK", R9A08G046_OSCCLK, CLK_EXTAL, 1, 1), }; static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { @@ -101,8 +296,116 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { MSTOP(BUS_REG1, BIT(2))), DEF_MOD("dmac_pclk", R9A08G046_DMAC_PCLK, R9A08G046_CLK_P3, 0x52c, 1, MSTOP(BUS_REG1, BIT(3))), + DEF_MOD("wdt0_pclk", R9A08G046_WDT0_PCLK, R9A08G046_CLK_P0, 0x548, 0, + MSTOP(BUS_REG0, BIT(0))), + DEF_MOD("wdt0_clk", R9A08G046_WDT0_CLK, R9A08G046_OSCCLK, 0x548, 1, + MSTOP(BUS_REG0, BIT(0))), + DEF_MOD("ssi0_pclk2", R9A08G046_SSI0_PCLK2, R9A08G046_CLK_P0, 0x570, 0, + MSTOP(BUS_MCPU1, BIT(10))), + DEF_MOD("ssi0_pclk_sfr", R9A08G046_SSI0_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 1, + MSTOP(BUS_MCPU1, BIT(10))), + DEF_MOD("ssi1_pclk2", R9A08G046_SSI1_PCLK2, R9A08G046_CLK_P0, 0x570, 2, + MSTOP(BUS_MCPU1, BIT(11))), + DEF_MOD("ssi1_pclk_sfr", R9A08G046_SSI1_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 3, + MSTOP(BUS_MCPU1, BIT(11))), + DEF_MOD("ssi2_pclk2", R9A08G046_SSI2_PCLK2, R9A08G046_CLK_P0, 0x570, 4, + MSTOP(BUS_MCPU1, BIT(12))), + DEF_MOD("ssi2_pclk_sfr", R9A08G046_SSI2_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 5, + MSTOP(BUS_MCPU1, BIT(12))), + DEF_MOD("ssi3_pclk2", R9A08G046_SSI3_PCLK2, R9A08G046_CLK_P0, 0x570, 6, + MSTOP(BUS_MCPU1, BIT(13))), + DEF_MOD("ssi3_pclk_sfr", R9A08G046_SSI3_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 7, + MSTOP(BUS_MCPU1, BIT(13))), + DEF_MOD("eth0_clk_axi", R9A08G046_ETH0_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 0, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_MOD("eth1_clk_axi", R9A08G046_ETH1_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 1, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_MOD("eth0_clk_chi", R9A08G046_ETH0_CLK_CHI, R9A08G046_CLK_P1, 0x57c, 2, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_MOD("eth1_clk_chi", R9A08G046_ETH1_CLK_CHI, R9A08G046_CLK_P1, 0x57c, 3, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_COUPLED("eth0_tx_i", R9A08G046_ETH0_CLK_TX_I, R9A08G046_CLK_ETHTX01, 0x57c, 4, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_COUPLED("eth0_tx_180_i", R9A08G046_ETH0_CLK_TX_180_I, R9A08G046_CLK_ETHTX02, 0x57c, 4, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_COUPLED("eth1_tx_i", R9A08G046_ETH1_CLK_TX_I, R9A08G046_CLK_ETHTX11, 0x57c, 5, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_COUPLED("eth1_tx_180_i", R9A08G046_ETH1_CLK_TX_180_I, R9A08G046_CLK_ETHTX12, 0x57c, 5, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_COUPLED("eth0_rx_i", R9A08G046_ETH0_CLK_RX_I, R9A08G046_CLK_ETHRX01, 0x57c, 6, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_COUPLED("eth0_rx_180_i", R9A08G046_ETH0_CLK_RX_180_I, R9A08G046_CLK_ETHRX02, 0x57c, 6, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_COUPLED("eth1_rx_i", R9A08G046_ETH1_CLK_RX_I, R9A08G046_CLK_ETHRX11, 0x57c, 7, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_COUPLED("eth1_rx_180_i", R9A08G046_ETH1_CLK_RX_180_I, R9A08G046_CLK_ETHRX12, 0x57c, 7, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_MOD("eth0_ptp_ref_i", R9A08G046_ETH0_CLK_PTP_REF_I, R9A08G046_CLK_HP, 0x57c, 8, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_MOD("eth1_ptp_ref_i", R9A08G046_ETH1_CLK_PTP_REF_I, R9A08G046_CLK_HP, 0x57c, 9, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_MOD("eth0_rmii_i", R9A08G046_ETH0_CLK_RMII_I, R9A08G046_CLK_ETHRM0, 0x57c, 10, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_MOD("eth1_rmii_i", R9A08G046_ETH1_CLK_RMII_I, R9A08G046_CLK_ETHRM1, 0x57c, 11, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_COUPLED("eth0_tx_i_rmii", R9A08G046_ETH0_CLK_TX_I_RMII, R9A08G046_CLK_ETHTX01, 0x57c, 12, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_COUPLED("eth0_rx_i_rmii", R9A08G046_ETH0_CLK_RX_I_RMII, R9A08G046_CLK_ETHRX01, 0x57c, 12, + MSTOP(BUS_PERI_COM, BIT(2))), + DEF_COUPLED("eth1_tx_i_rmii", R9A08G046_ETH1_CLK_TX_I_RMII, R9A08G046_CLK_ETHTX11, 0x57c, 13, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_COUPLED("eth1_rx_i_rmii", R9A08G046_ETH1_CLK_RX_I_RMII, R9A08G046_CLK_ETHRX11, 0x57c, 13, + MSTOP(BUS_PERI_COM, BIT(3))), + DEF_MOD("i2c0_pclk", R9A08G046_I2C0_PCLK, R9A08G046_CLK_P0, 0x580, 0, + MSTOP(BUS_MCPU2, BIT(10))), + DEF_MOD("i2c1_pclk", R9A08G046_I2C1_PCLK, R9A08G046_CLK_P0, 0x580, 1, + MSTOP(BUS_MCPU2, BIT(11))), + DEF_MOD("i2c2_pclk", R9A08G046_I2C2_PCLK, R9A08G046_CLK_P0, 0x580, 2, + MSTOP(BUS_MCPU2, BIT(12))), + DEF_MOD("i2c3_pclk", R9A08G046_I2C3_PCLK, R9A08G046_CLK_P0, 0x580, 3, + MSTOP(BUS_MCPU2, BIT(13))), DEF_MOD("scif0_clk_pck", R9A08G046_SCIF0_CLK_PCK, R9A08G046_CLK_P0, 0x584, 0, MSTOP(BUS_MCPU2, BIT(1))), + DEF_MOD("scif1_clk_pck", R9A08G046_SCIF1_CLK_PCK, R9A08G046_CLK_P0, 0x584, 1, + MSTOP(BUS_MCPU2, BIT(2))), + DEF_MOD("scif2_clk_pck", R9A08G046_SCIF2_CLK_PCK, R9A08G046_CLK_P0, 0x584, 2, + MSTOP(BUS_MCPU2, BIT(3))), + DEF_MOD("scif3_clk_pck", R9A08G046_SCIF3_CLK_PCK, R9A08G046_CLK_P0, 0x584, 3, + MSTOP(BUS_MCPU2, BIT(4))), + DEF_MOD("scif4_clk_pck", R9A08G046_SCIF4_CLK_PCK, R9A08G046_CLK_P0, 0x584, 4, + MSTOP(BUS_MCPU2, BIT(5))), + DEF_MOD("scif5_clk_pck", R9A08G046_SCIF5_CLK_PCK, R9A08G046_CLK_P0, 0x584, 5, + MSTOP(BUS_MCPU3, BIT(4))), + DEF_MOD("rspi0_pclk", R9A08G046_RSPI0_PCLK, R9A08G046_CLK_P3, 0x590, 0, + MSTOP(BUS_MCPU1, BIT(14))), + DEF_MOD("rspi1_pclk", R9A08G046_RSPI1_PCLK, R9A08G046_CLK_P3, 0x590, 1, + MSTOP(BUS_MCPU1, BIT(15))), + DEF_MOD("rspi2_pclk", R9A08G046_RSPI2_PCLK, R9A08G046_CLK_P3, 0x590, 2, + MSTOP(BUS_MCPU2, BIT(0))), + DEF_MOD("rspi0_tclk", R9A08G046_RSPI0_TCLK, R9A08G046_CLK_P17, 0x590, 8, + MSTOP(BUS_MCPU1, BIT(14))), + DEF_MOD("rspi1_tclk", R9A08G046_RSPI1_TCLK, R9A08G046_CLK_P18, 0x590, 9, + MSTOP(BUS_MCPU1, BIT(15))), + DEF_MOD("rspi2_tclk", R9A08G046_RSPI2_TCLK, R9A08G046_CLK_P19, 0x590, 10, + MSTOP(BUS_MCPU2, BIT(0))), + DEF_MOD("gpio_hclk", R9A08G046_GPIO_HCLK, R9A08G046_OSCCLK, 0x598, 0, + MSTOP(BUS_PERI_CPU, BIT(6))), + DEF_MOD("rsci0_pclk", R9A08G046_RSCI0_PCLK, R9A08G046_CLK_P0, 0x618, 0, + MSTOP(BUS_MCPU2, BIT(7))), + DEF_MOD("rsci1_pclk", R9A08G046_RSCI1_PCLK, R9A08G046_CLK_P0, 0x618, 1, + MSTOP(BUS_MCPU2, BIT(8))), + DEF_MOD("rsci2_pclk", R9A08G046_RSCI2_PCLK, R9A08G046_CLK_P0, 0x618, 2, + MSTOP(BUS_MCPU3, BIT(11))), + DEF_MOD("rsci3_pclk", R9A08G046_RSCI3_PCLK, R9A08G046_CLK_P0, 0x618, 3, + MSTOP(BUS_MCPU3, BIT(12))), + DEF_MOD("rsci0_tclk", R9A08G046_RSCI0_TCLK, R9A08G046_CLK_P13, 0x618, 8, + MSTOP(BUS_MCPU2, BIT(7))), + DEF_MOD("rsci1_tclk", R9A08G046_RSCI1_TCLK, R9A08G046_CLK_P14, 0x618, 9, + MSTOP(BUS_MCPU2, BIT(8))), + DEF_MOD("rsci2_tclk", R9A08G046_RSCI2_TCLK, R9A08G046_CLK_P15, 0x618, 10, + MSTOP(BUS_MCPU3, BIT(11))), + DEF_MOD("rsci3_tclk", R9A08G046_RSCI3_TCLK, R9A08G046_CLK_P16, 0x618, 11, + MSTOP(BUS_MCPU3, BIT(12))), }; static const struct rzg2l_reset r9a08g046_resets[] = { @@ -111,11 +414,45 @@ static const struct rzg2l_reset r9a08g046_resets[] = { DEF_RST(R9A08G046_IA55_RESETN, 0x818, 0), DEF_RST(R9A08G046_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A08G046_DMAC_RST_ASYNC, 0x82c, 1), + DEF_RST(R9A08G046_WDT0_PRESETN, 0x848, 0), + DEF_RST(R9A08G046_SSI0_RST_M2_REG, 0x870, 0), + DEF_RST(R9A08G046_SSI1_RST_M2_REG, 0x870, 1), + DEF_RST(R9A08G046_SSI2_RST_M2_REG, 0x870, 2), + DEF_RST(R9A08G046_SSI3_RST_M2_REG, 0x870, 3), + DEF_RST(R9A08G046_ETH0_ARESET_N, 0x87c, 0), + DEF_RST(R9A08G046_ETH1_ARESET_N, 0x87c, 1), + DEF_RST(R9A08G046_I2C0_MRST, 0x880, 0), + DEF_RST(R9A08G046_I2C1_MRST, 0x880, 1), + DEF_RST(R9A08G046_I2C2_MRST, 0x880, 2), + DEF_RST(R9A08G046_I2C3_MRST, 0x880, 3), DEF_RST(R9A08G046_SCIF0_RST_SYSTEM_N, 0x884, 0), + DEF_RST(R9A08G046_SCIF1_RST_SYSTEM_N, 0x884, 1), + DEF_RST(R9A08G046_SCIF2_RST_SYSTEM_N, 0x884, 2), + DEF_RST(R9A08G046_SCIF3_RST_SYSTEM_N, 0x884, 3), + DEF_RST(R9A08G046_SCIF4_RST_SYSTEM_N, 0x884, 4), + DEF_RST(R9A08G046_SCIF5_RST_SYSTEM_N, 0x884, 5), + DEF_RST(R9A08G046_RSPI0_PRESETN, 0x890, 0), + DEF_RST(R9A08G046_RSPI1_PRESETN, 0x890, 1), + DEF_RST(R9A08G046_RSPI2_PRESETN, 0x890, 2), + DEF_RST(R9A08G046_RSPI0_TRESETN, 0x890, 8), + DEF_RST(R9A08G046_RSPI1_TRESETN, 0x890, 9), + DEF_RST(R9A08G046_RSPI2_TRESETN, 0x890, 10), + DEF_RST(R9A08G046_GPIO_RSTN, 0x898, 0), + DEF_RST(R9A08G046_GPIO_PORT_RESETN, 0x898, 1), + DEF_RST(R9A08G046_GPIO_SPARE_RESETN, 0x898, 2), + DEF_RST(R9A08G046_RSCI0_PRESETN, 0x918, 0), + DEF_RST(R9A08G046_RSCI1_PRESETN, 0x918, 1), + DEF_RST(R9A08G046_RSCI2_PRESETN, 0x918, 2), + DEF_RST(R9A08G046_RSCI3_PRESETN, 0x918, 3), + DEF_RST(R9A08G046_RSCI0_TRESETN, 0x918, 8), + DEF_RST(R9A08G046_RSCI1_TRESETN, 0x918, 9), + DEF_RST(R9A08G046_RSCI2_TRESETN, 0x918, 10), + DEF_RST(R9A08G046_RSCI3_TRESETN, 0x918, 11), }; static const unsigned int r9a08g046_crit_mod_clks[] __initconst = { MOD_CLK_BASE + R9A08G046_GIC600_GICCLK, + MOD_CLK_BASE + R9A08G046_IA55_PCLK, MOD_CLK_BASE + R9A08G046_IA55_CLK, MOD_CLK_BASE + R9A08G046_DMAC_ACLK, }; @@ -125,6 +462,23 @@ static const unsigned int r9a08g046_crit_resets[] = { R9A08G046_DMAC_RST_ASYNC, }; +static const unsigned int r9a08g046_no_pm_mod_clks[] = { + MOD_CLK_BASE + R9A08G046_ETH0_CLK_TX_I, + MOD_CLK_BASE + R9A08G046_ETH0_CLK_TX_180_I, + MOD_CLK_BASE + R9A08G046_ETH0_CLK_RX_I, + MOD_CLK_BASE + R9A08G046_ETH0_CLK_RX_180_I, + MOD_CLK_BASE + R9A08G046_ETH0_CLK_RMII_I, + MOD_CLK_BASE + R9A08G046_ETH0_CLK_TX_I_RMII, + MOD_CLK_BASE + R9A08G046_ETH0_CLK_RX_I_RMII, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_I, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_180_I, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_I, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_180_I, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_RMII_I, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_I_RMII, + MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_I_RMII, +}; + const struct rzg2l_cpg_info r9a08g046_cpg_info = { /* Core Clocks */ .core_clks = r9a08g046_core_clks, @@ -141,6 +495,10 @@ const struct rzg2l_cpg_info r9a08g046_cpg_info = { .num_mod_clks = ARRAY_SIZE(r9a08g046_mod_clks), .num_hw_mod_clks = R9A08G046_BSC_X_BCK_BSC + 1, + /* No PM modules Clocks */ + .no_pm_mod_clks = r9a08g046_no_pm_mod_clks, + .num_no_pm_mod_clks = ARRAY_SIZE(r9a08g046_no_pm_mod_clks), + /* Resets */ .resets = r9a08g046_resets, .num_resets = R9A08G046_BSC_X_PRESET_BSC + 1, /* Last reset ID + 1 */ diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c index e59ac4a05a7f5..94158b6834e6e 100644 --- a/drivers/clk/renesas/r9a09g047-cpg.c +++ b/drivers/clk/renesas/r9a09g047-cpg.c @@ -6,6 +6,7 @@ */ #include <linux/clk-provider.h> +#include <linux/clk/renesas.h> #include <linux/device.h> #include <linux/init.h> #include <linux/kernel.h> @@ -30,6 +31,8 @@ enum clk_ids { CLK_PLLCA55, CLK_PLLVDO, CLK_PLLETH, + CLK_PLLDSI0, + CLK_PLLDSI1, /* Internal Core Clocks */ CLK_PLLCM33_DIV3, @@ -57,6 +60,8 @@ enum clk_ids { CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, CLK_CSDIV_PLLETH_GBE1, + CLK_SMUX2_DSI0_CLK, + CLK_SMUX2_DSI1_CLK, CLK_SMUX2_GBE0_TXCLK, CLK_SMUX2_GBE0_RXCLK, CLK_SMUX2_GBE1_TXCLK, @@ -64,6 +69,12 @@ enum clk_ids { CLK_PLLDTY_DIV16, CLK_PLLVDO_CRU0, CLK_PLLVDO_GPU, + CLK_PLLETH_DIV4_LPCLK, + CLK_PLLETH_LPCLK, + CLK_PLLDSI0_DIV7, + CLK_PLLDSI1_DIV7, + CLK_PLLDSI0_CSDIV, + CLK_PLLDSI1_CSDIV, /* Module Clocks */ MOD_CLK_BASE, @@ -91,6 +102,18 @@ static const struct clk_div_table dtable_2_16[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_16_plldsi[] = { + {0, 2}, + {1, 4}, + {2, 6}, + {3, 8}, + {4, 10}, + {5, 12}, + {6, 14}, + {7, 16}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_64[] = { {0, 2}, {1, 4}, @@ -107,7 +130,23 @@ static const struct clk_div_table dtable_2_100[] = { {0, 0}, }; +static const struct clk_div_table dtable_16_128[] = { + {0, 16}, + {1, 32}, + {2, 64}, + {3, 128}, + {0, 0}, +}; + +RZG3E_CPG_PLL_DSI0_LIMITS(rzg3e_cpg_pll_dsi0_limits); +RZG3E_CPG_PLL_DSI1_LIMITS(rzg3e_cpg_pll_dsi1_limits); + +#define PLLDSI0 PLL_PACK_LIMITS(0xc0, 1, 0, &rzg3e_cpg_pll_dsi0_limits) +#define PLLDSI1 PLL_PACK_LIMITS(0x160, 1, 1, &rzg3e_cpg_pll_dsi1_limits) + /* Mux clock tables */ +static const char * const smux2_dsi0_clk[] = { ".plldsi0_div7", ".plldsi0_csdiv" }; +static const char * const smux2_dsi1_clk[] = { ".plldsi1_div7", ".plldsi1_csdiv" }; static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" }; static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" }; static const char * const smux2_gbe1_rxclk[] = { ".plleth_gbe1", "et1_rxclk" }; @@ -128,6 +167,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55), DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3), DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2), + DEF_PLLDSI(".plldsi0", CLK_PLLDSI0, CLK_QEXTAL, PLLDSI0), + DEF_PLLDSI(".plldsi1", CLK_PLLDSI1, CLK_QEXTAL, PLLDSI1), /* Internal Core Clocks */ DEF_FIXED(".pllcm33_div3", CLK_PLLCM33_DIV3, CLK_PLLCM33, 1, 3), @@ -171,6 +212,21 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), DEF_DDIV(".pllvdo_gpu", CLK_PLLVDO_GPU, CLK_PLLVDO, CDDIV3_DIVCTL1, dtable_2_64), + DEF_FIXED(".plleth_div4_lpclk", CLK_PLLETH_DIV4_LPCLK, CLK_PLLETH, 1, 4), + DEF_CSDIV(".plleth_lpclk", CLK_PLLETH_LPCLK, CLK_PLLETH_DIV4_LPCLK, + CSDIV0_DIVCTL2, dtable_16_128), + + DEF_PLLDSI_DIV(".plldsi0_csdiv", CLK_PLLDSI0_CSDIV, CLK_PLLDSI0, + CSDIV1_DIVCTL2, dtable_2_16_plldsi), + DEF_PLLDSI_DIV(".plldsi1_csdiv", CLK_PLLDSI1_CSDIV, CLK_PLLDSI1, + CSDIV1_DIVCTL3, dtable_2_16_plldsi), + DEF_FIXED(".plldsi0_div7", CLK_PLLDSI0_DIV7, CLK_PLLDSI0, 1, 7), + DEF_FIXED(".plldsi1_div7", CLK_PLLDSI1_DIV7, CLK_PLLDSI1, 1, 7), + DEF_PLLDSI_SMUX(".smux2_dsi0_clk", CLK_SMUX2_DSI0_CLK, + SSEL3_SELCTL0, smux2_dsi0_clk), + DEF_PLLDSI_SMUX(".smux2_dsi1_clk", CLK_SMUX2_DSI1_CLK, + SSEL3_SELCTL1, smux2_dsi1_clk), + /* Core Clocks */ DEF_FIXED("sys_0_pclk", R9A09G047_SYS_0_PCLK, CLK_QEXTAL, 1, 1), DEF_DDIV("ca55_0_coreclk0", R9A09G047_CA55_0_CORECLK0, CLK_PLLCA55, @@ -452,6 +508,22 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(9, BIT(4))), DEF_MOD("cru_0_pclk", CLK_PLLDTY_DIV16, 13, 4, 6, 20, BUS_MSTOP(9, BIT(4))), + DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, + BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, + BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("dsi_0_vclk1", CLK_SMUX2_DSI0_CLK, 14, 10, 7, 10, + BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK, 14, 11, 7, 11, + BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12, + BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13, + BUS_MSTOP(10, BIT(3) | BIT(2) | BIT(1))), + DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14, + BUS_MSTOP(10, BIT(3) | BIT(2) | BIT(1))), + DEF_MOD("lcdc_0_clk_d", CLK_SMUX2_DSI0_CLK, 14, 15, 7, 15, + BUS_MSTOP(10, BIT(3) | BIT(2) | BIT(1))), DEF_MOD("ge3d_clk", CLK_PLLVDO_GPU, 15, 0, 7, 16, BUS_MSTOP(3, BIT(4))), DEF_MOD("ge3d_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17, @@ -460,6 +532,14 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(3, BIT(4))), DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10, BUS_MSTOP(2, BIT(15))), + DEF_MOD("dsi_0_vclk2", CLK_SMUX2_DSI1_CLK, 25, 0, 10, 21, + BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("lcdc_1_clk_a", CLK_PLLDTY_ACPU_DIV2, 26, 8, 10, 30, + BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))), + DEF_MOD("lcdc_1_clk_p", CLK_PLLDTY_DIV16, 26, 9, 10, 31, + BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))), + DEF_MOD("lcdc_1_clk_d", CLK_SMUX2_DSI1_CLK, 26, 10, 11, 0, + BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))), }; static const struct rzv2h_reset r9a09g047_resets[] __initconst = { @@ -535,10 +615,14 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */ DEF_RST(12, 6, 5, 23), /* CRU_0_ARESETN */ DEF_RST(12, 7, 5, 24), /* CRU_0_S_RESETN */ + DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ + DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ + DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ DEF_RST(13, 13, 6, 14), /* GE3D_RESETN */ DEF_RST(13, 14, 6, 15), /* GE3D_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GE3D_ACE_RESETN */ DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */ + DEF_RST(17, 14, 8, 15), /* LCDC_1_RESET_N */ }; const struct rzv2h_cpg_info r9a09g047_cpg_info __initconst = { diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 93b15e06a19bc..f777601a23b93 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -257,6 +257,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("spi0", 104, CLK_SPI0ASYNC), DEF_MOD("spi1", 105, CLK_SPI1ASYNC), DEF_MOD("spi2", 106, CLK_SPI2ASYNC), + DEF_MOD("mtu3", 200, R9A09G077_CLK_PCLKH), DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH), DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 26ea85cfaa027..5b84cbee030b8 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -370,6 +370,9 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, struct clk *clk; int range_check; + if (clkspec->args_count != 2) + return ERR_PTR(-EINVAL); + switch (clkspec->args[0]) { case CPG_CORE: type = "core"; diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index abfd8634d2bef..426e93dc7a989 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -58,6 +58,13 @@ #define RZG3S_DIV_NF GENMASK(12, 1) #define RZG3S_SEL_PLL BIT(0) +#define RZG3L_PLL_STBY_OFFSET(x) (GET_REG_SAMPLL_CLK1(x) - 0x4) +#define RZG3L_PLL_STBY_RESETB BIT(0) +#define RZG3L_PLL_STBY_RESETB_WEN BIT(16) +#define RZG3L_PLL_MON_OFFSET(x) (GET_REG_SAMPLL_CLK1(x) + 0x8) +#define RZG3L_PLL_MON_RESETB BIT(0) +#define RZG3L_PLL_MON_LOCK BIT(4) + #define CLK_ON_R(reg) (reg) #define CLK_MON_R(reg) (0x180 + (reg)) #define CLK_RST_R(reg) (reg) @@ -1107,9 +1114,6 @@ static unsigned long rzg3s_cpg_pll_clk_recalc_rate(struct clk_hw *hw, u32 nir, nfr, mr, pr, val, setting; u64 rate; - if (pll_clk->type != CLK_TYPE_G3S_PLL) - return parent_rate; - setting = GET_REG_SAMPLL_SETTING(pll_clk->conf); if (setting) { val = readl(priv->base + setting); @@ -1178,6 +1182,61 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, return pll_clk->hw.clk; } +static int rzg3l_cpg_pll_clk_is_enabled(struct clk_hw *hw) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + u32 val = readl(priv->base + RZG3L_PLL_MON_OFFSET(pll_clk->conf)); + u32 mon_val = RZG3L_PLL_MON_RESETB | RZG3L_PLL_MON_LOCK; + + /* Ensure both RESETB and LOCK bits are set */ + return (mon_val == (val & mon_val)); +} + +static int rzg3l_cpg_pll_clk_endisable(struct clk_hw *hw, bool enable) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + u32 mon_mask = RZG3L_PLL_MON_RESETB | RZG3L_PLL_MON_LOCK; + u32 val = RZG3L_PLL_STBY_RESETB_WEN; + u32 stby_offset, mon_offset; + u32 mon_val = 0; + int ret; + + stby_offset = RZG3L_PLL_STBY_OFFSET(pll_clk->conf); + mon_offset = RZG3L_PLL_MON_OFFSET(pll_clk->conf); + + if (enable) { + val |= RZG3L_PLL_STBY_RESETB; + mon_val = mon_mask; + } + + writel(val, priv->base + stby_offset); + + /* ensure PLL is in normal/standby mode */ + ret = readl_poll_timeout_atomic(priv->base + mon_offset, val, + mon_val == (val & mon_mask), 10, 100); + if (ret) + dev_err(priv->dev, "Failed to %s PLL 0x%x/%pC\n", enable ? + "enable" : "disable", stby_offset, hw->clk); + + return ret; +} + +static int rzg3l_cpg_pll_clk_enable(struct clk_hw *hw) +{ + if (rzg3l_cpg_pll_clk_is_enabled(hw)) + return 0; + + return rzg3l_cpg_pll_clk_endisable(hw, true); +} + +static const struct clk_ops rzg3l_cpg_pll_ops = { + .is_enabled = rzg3l_cpg_pll_clk_is_enabled, + .enable = rzg3l_cpg_pll_clk_enable, + .recalc_rate = rzg3s_cpg_pll_clk_recalc_rate, +}; + static struct clk *rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, void *data) @@ -1261,6 +1320,9 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_SAM_PLL: clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops); break; + case CLK_TYPE_G3L_PLL: + clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3l_cpg_pll_ops); + break; case CLK_TYPE_G3S_PLL: clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops); break; diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index 10baf9e71a6e0..33f54ba0e64ee 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -123,6 +123,7 @@ enum clk_types { CLK_TYPE_IN, /* External Clock Input */ CLK_TYPE_FF, /* Fixed Factor Clock */ CLK_TYPE_SAM_PLL, + CLK_TYPE_G3L_PLL, CLK_TYPE_G3S_PLL, /* Clock with divider */ @@ -152,6 +153,9 @@ enum clk_types { DEF_TYPE(_name, _id, _type, .parent = _parent) #define DEF_SAMPLL(_name, _id, _parent, _conf) \ DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) +#define DEF_G3L_PLL(_name, _id, _parent, _conf, _default_rate) \ + DEF_TYPE(_name, _id, CLK_TYPE_G3L_PLL, .parent = _parent, .conf = _conf, \ + .default_rate = _default_rate) #define DEF_G3S_PLL(_name, _id, _parent, _conf, _default_rate) \ DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf, \ .default_rate = _default_rate) @@ -174,11 +178,14 @@ enum clk_types { .invalid_rate = _invalid_rate, \ .max_rate = _max_rate, .flag = (_clk_flags), \ .notifier = _notif) -#define DEF_MUX(_name, _id, _conf, _parent_names) \ +#define DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, _flag) \ DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \ .parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ - .mux_flags = CLK_MUX_HIWORD_MASK) + .mux_flags = CLK_MUX_HIWORD_MASK, \ + .flag = _flag) +#define DEF_MUX(_name, _id, _conf, _parent_names) \ + DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, 0) #define DEF_MUX_RO(_name, _id, _conf, _parent_names) \ DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \ .parent_names = _parent_names, \ diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index f6c47fb89bca5..e271c04cee34f 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -76,6 +76,11 @@ /* On RZ/G3E SoC we have two DSI PLLs */ #define MAX_CPG_DSI_PLL 2 +#define CPG_PLLDSI_SMUX_LVDS_DUTY_NUM 4 +#define CPG_PLLDSI_SMUX_LVDS_DUTY_DEN 7 +#define CPG_PLLDSI_SMUX_DSI_RGB_DUTY_NUM 1 +#define CPG_PLLDSI_SMUX_DSI_RGB_DUTY_DEN 2 + /** * struct rzv2h_pll_dsi_info - PLL DSI information, holds the limits and parameters * @@ -418,6 +423,20 @@ bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, } EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG"); +/** + * struct rzv2h_plldsi_mux_clk - PLL DSI MUX clock + * + * @priv: CPG private data + * @mux: mux clk + */ +struct rzv2h_plldsi_mux_clk { + struct rzv2h_cpg_priv *priv; + struct clk_mux mux; +}; + +#define to_plldsi_clk_mux(_mux) \ + container_of(_mux, struct rzv2h_plldsi_mux_clk, mux) + static unsigned long rzv2h_cpg_plldsi_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -649,6 +668,165 @@ static int rzv2h_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate, return rzv2h_cpg_pll_set_rate(pll_clk, &dsi_info->pll_dsi_parameters.pll, true); } +static u8 rzv2h_cpg_plldsi_smux_get_parent(struct clk_hw *hw) +{ + return clk_mux_ops.get_parent(hw); +} + +static int rzv2h_cpg_plldsi_smux_set_parent(struct clk_hw *hw, u8 index) +{ + return clk_mux_ops.set_parent(hw, index); +} + +static int rzv2h_cpg_plldsi_smux_lvds_determine_rate(struct rzv2h_cpg_priv *priv, + struct pll_clk *pll_clk, + struct clk_rate_request *req) +{ + struct rzv2h_pll_div_pars *dsi_params; + struct rzv2h_pll_dsi_info *dsi_info; + u8 lvds_table[] = { 7 }; + u64 rate_millihz; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + dsi_params = &dsi_info->pll_dsi_parameters; + + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (!rzv2h_get_pll_divs_pars(dsi_info->pll_dsi_limits, dsi_params, + lvds_table, ARRAY_SIZE(lvds_table), rate_millihz)) { + dev_err(priv->dev, "failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + + req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params->div.freq_millihz, MILLI); + req->best_parent_rate = req->rate; + dsi_info->req_pll_dsi_rate = req->best_parent_rate * dsi_params->div.divider_value; + + return 0; +} + +static int rzv2h_cpg_plldsi_smux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_mux *mux = to_clk_mux(hw); + struct rzv2h_plldsi_mux_clk *dsi_mux = to_plldsi_clk_mux(mux); + struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw)); + struct rzv2h_cpg_priv *priv = dsi_mux->priv; + + /* + * For LVDS output (parent index 0), calculate PLL parameters with + * fixed divider value of 7. For DSI/RGB output (parent index 1) skip + * PLL calculation here as it's handled by determine_rate of the + * divider (up one level). + */ + if (!clk_mux_ops.get_parent(hw)) + return rzv2h_cpg_plldsi_smux_lvds_determine_rate(priv, pll_clk, req); + + req->best_parent_rate = req->rate; + return 0; +} + +static int rzv2h_cpg_plldsi_smux_get_duty_cycle(struct clk_hw *hw, + struct clk_duty *duty) +{ + u8 parent = clk_mux_ops.get_parent(hw); + + /* + * CDIV7_DSIx_CLK - LVDS path (div7) - duty 4/7. + * CSDIV_DSIx - DSI/RGB path (csdiv) - duty 1/2. + */ + if (parent == 0) { + duty->num = CPG_PLLDSI_SMUX_LVDS_DUTY_NUM; + duty->den = CPG_PLLDSI_SMUX_LVDS_DUTY_DEN; + } else { + duty->num = CPG_PLLDSI_SMUX_DSI_RGB_DUTY_NUM; + duty->den = CPG_PLLDSI_SMUX_DSI_RGB_DUTY_DEN; + } + + return 0; +} + +static int rzv2h_cpg_plldsi_smux_set_duty_cycle(struct clk_hw *hw, + struct clk_duty *duty) +{ + struct clk_hw *parent_hw; + u8 parent_idx; + + /* + * Select parent based on requested duty cycle: + * - If duty > 50% (num/den > 1/2), select LVDS path (parent 0) + * - Otherwise, select DSI/RGB path (parent 1) + */ + if (duty->num * CPG_PLLDSI_SMUX_DSI_RGB_DUTY_DEN > + duty->den * CPG_PLLDSI_SMUX_DSI_RGB_DUTY_NUM) + parent_idx = 0; + else + parent_idx = 1; + + if (parent_idx >= clk_hw_get_num_parents(hw)) + return -EINVAL; + + parent_hw = clk_hw_get_parent_by_index(hw, parent_idx); + if (!parent_hw) + return -EINVAL; + + return clk_hw_set_parent(hw, parent_hw); +} + +static const struct clk_ops rzv2h_cpg_plldsi_smux_ops = { + .determine_rate = rzv2h_cpg_plldsi_smux_determine_rate, + .get_parent = rzv2h_cpg_plldsi_smux_get_parent, + .set_parent = rzv2h_cpg_plldsi_smux_set_parent, + .get_duty_cycle = rzv2h_cpg_plldsi_smux_get_duty_cycle, + .set_duty_cycle = rzv2h_cpg_plldsi_smux_set_duty_cycle, +}; + +static struct clk * __init +rzv2h_cpg_plldsi_smux_clk_register(const struct cpg_core_clk *core, + struct rzv2h_cpg_priv *priv) +{ + struct rzv2h_plldsi_mux_clk *clk_hw_data; + struct clk_init_data init; + struct clk_hw *clk_hw; + struct smuxed smux; + int ret; + + smux = core->cfg.smux; + + if (smux.shift + smux.width > 16) { + dev_err(priv->dev, "mux value exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + + clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); + if (!clk_hw_data) + return ERR_PTR(-ENOMEM); + + clk_hw_data->priv = priv; + + init.name = core->name; + init.ops = &rzv2h_cpg_plldsi_smux_ops; + init.flags = core->flag; + init.parent_names = core->parent_names; + init.num_parents = core->num_parents; + + clk_hw_data->mux.reg = priv->base + smux.offset; + + clk_hw_data->mux.shift = smux.shift; + clk_hw_data->mux.mask = clk_div_mask(smux.width); + clk_hw_data->mux.flags = core->mux_flags; + clk_hw_data->mux.lock = &priv->rmw_lock; + + clk_hw = &clk_hw_data->mux.hw; + clk_hw->init = &init; + + ret = devm_clk_hw_register(priv->dev, clk_hw); + if (ret) + return ERR_PTR(ret); + + return clk_hw->clk; +} + static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw) { struct pll_clk *pll_clk = to_pll(hw); @@ -1085,6 +1263,9 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_PLLDSI_DIV: clk = rzv2h_cpg_plldsi_div_clk_register(core, priv); break; + case CLK_TYPE_PLLDSI_SMUX: + clk = rzv2h_cpg_plldsi_smux_clk_register(core, priv); + break; default: goto fail; } diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index dc957bdaf5e97..dec0f7b621d66 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -121,6 +121,7 @@ struct fixed_mod_conf { #define CPG_SSEL0 (0x300) #define CPG_SSEL1 (0x304) +#define CPG_SSEL3 (0x30C) #define CPG_CDDIV0 (0x400) #define CPG_CDDIV1 (0x404) #define CPG_CDDIV2 (0x408) @@ -148,6 +149,7 @@ struct fixed_mod_conf { #define CSDIV0_DIVCTL2 DDIV_PACK(CPG_CSDIV0, 8, 2, CSDIV_NO_MON) #define CSDIV0_DIVCTL3 DDIV_PACK_NO_RMW(CPG_CSDIV0, 12, 2, CSDIV_NO_MON) #define CSDIV1_DIVCTL2 DDIV_PACK(CPG_CSDIV1, 8, 4, CSDIV_NO_MON) +#define CSDIV1_DIVCTL3 DDIV_PACK(CPG_CSDIV1, 12, 4, CSDIV_NO_MON) #define SSEL0_SELCTL2 SMUX_PACK(CPG_SSEL0, 8, 1) #define SSEL0_SELCTL3 SMUX_PACK(CPG_SSEL0, 12, 1) @@ -155,6 +157,8 @@ struct fixed_mod_conf { #define SSEL1_SELCTL1 SMUX_PACK(CPG_SSEL1, 4, 1) #define SSEL1_SELCTL2 SMUX_PACK(CPG_SSEL1, 8, 1) #define SSEL1_SELCTL3 SMUX_PACK(CPG_SSEL1, 12, 1) +#define SSEL3_SELCTL0 SMUX_PACK(CPG_SSEL3, 0, 1) +#define SSEL3_SELCTL1 SMUX_PACK(CPG_SSEL3, 4, 1) #define BUS_MSTOP_IDX_MASK GENMASK(31, 16) #define BUS_MSTOP_BITS_MASK GENMASK(15, 0) @@ -203,6 +207,7 @@ enum clk_types { CLK_TYPE_SMUX, /* Static Mux */ CLK_TYPE_PLLDSI, /* PLLDSI */ CLK_TYPE_PLLDSI_DIV, /* PLLDSI divider */ + CLK_TYPE_PLLDSI_SMUX, /* PLLDSI Static Mux */ }; #define DEF_TYPE(_name, _id, _type...) \ @@ -241,6 +246,13 @@ enum clk_types { .dtable = _dtable, \ .parent = _parent, \ .flag = CLK_SET_RATE_PARENT) +#define DEF_PLLDSI_SMUX(_name, _id, _smux_packed, _parent_names) \ + DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI_SMUX, \ + .cfg.smux = _smux_packed, \ + .parent_names = _parent_names, \ + .num_parents = ARRAY_SIZE(_parent_names), \ + .flag = CLK_SET_RATE_PARENT, \ + .mux_flags = CLK_MUX_HIWORD_MASK) /** * struct rzv2h_mod_clk - Module Clocks definitions diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c index 805b954812817..3ce1a906fb0c3 100644 --- a/drivers/clk/visconti/pll.c +++ b/drivers/clk/visconti/pll.c @@ -21,9 +21,9 @@ struct visconti_pll { void __iomem *pll_base; spinlock_t *lock; unsigned long flags; - const struct visconti_pll_rate_table *rate_table; size_t rate_count; struct visconti_pll_provider *ctx; + struct visconti_pll_rate_table rate_table[] __counted_by(rate_count); }; #define PLL_CONF_REG 0x0000 @@ -255,10 +255,6 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, size_t len; int ret; - pll = kzalloc_obj(*pll); - if (!pll) - return ERR_PTR(-ENOMEM); - init.name = name; init.flags = CLK_IGNORE_UNUSED; init.parent_names = &parent_name; @@ -266,11 +262,13 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, for (len = 0; rate_table[len].rate != 0; ) len++; + + pll = kzalloc_flex(*pll, rate_table, len); + if (!pll) + return ERR_PTR(-ENOMEM); + pll->rate_count = len; - pll->rate_table = kmemdup_array(rate_table, - pll->rate_count, sizeof(*pll->rate_table), - GFP_KERNEL); - WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name); + memcpy(pll->rate_table, rate_table, len * sizeof(*pll->rate_table)); init.ops = &visconti_pll_ops; pll->hw.init = &init; @@ -282,7 +280,6 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, ret = clk_hw_register(NULL, &pll->hw); if (ret) { pr_err("failed to register pll clock %s : %d\n", name, ret); - kfree(pll->rate_table); kfree(pll); pll_hw_clk = ERR_PTR(ret); } diff --git a/include/linux/adi-axi-common.h b/include/linux/adi-axi-common.h index 37962ba530dfc..e7ba393061ee6 100644 --- a/include/linux/adi-axi-common.h +++ b/include/linux/adi-axi-common.h @@ -51,6 +51,7 @@ enum adi_axi_fpga_technology { ADI_AXI_FPGA_TECH_SERIES7, ADI_AXI_FPGA_TECH_ULTRASCALE, ADI_AXI_FPGA_TECH_ULTRASCALE_PLUS, + ADI_AXI_FPGA_TECH_VERSAL, }; enum adi_axi_fpga_family { @@ -71,6 +72,7 @@ enum adi_axi_fpga_speed_grade { ADI_AXI_FPGA_SPEED_2 = 20, ADI_AXI_FPGA_SPEED_2L = 21, ADI_AXI_FPGA_SPEED_2LV = 22, + ADI_AXI_FPGA_SPEED_2MP = 23, ADI_AXI_FPGA_SPEED_3 = 30, }; diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index c360df9fa735c..0949400f44de4 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -164,6 +164,26 @@ struct rzv2h_pll_div_pars { .k = { .min = -32768, .max = 32767 }, \ } \ +#define RZG3E_CPG_PLL_DSI0_LIMITS(name) \ + static const struct rzv2h_pll_limits (name) = { \ + .fout = { .min = 25 * MEGA, .max = 1218 * MEGA }, \ + .fvco = { .min = 1600 * MEGA, .max = 3200 * MEGA }, \ + .m = { .min = 64, .max = 533 }, \ + .p = { .min = 1, .max = 4 }, \ + .s = { .min = 0, .max = 6 }, \ + .k = { .min = -32768, .max = 32767 }, \ + } \ + +#define RZG3E_CPG_PLL_DSI1_LIMITS(name) \ + static const struct rzv2h_pll_limits (name) = { \ + .fout = { .min = 25 * MEGA, .max = 609 * MEGA }, \ + .fvco = { .min = 1600 * MEGA, .max = 3200 * MEGA }, \ + .m = { .min = 64, .max = 533 }, \ + .p = { .min = 1, .max = 4 }, \ + .s = { .min = 0, .max = 6 }, \ + .k = { .min = -32768, .max = 32767 }, \ + } \ + #ifdef CONFIG_CLK_RZV2H bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, struct rzv2h_pll_pars *pars, u64 freq_millihz); |
