Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branches 'clk-imx', 'clk-allwinner' and 'clk-ti' into clk-next

* clk-imx:
clk: imx95-blk-ctl: Save/restore registers when RPM routines are called
clk: imx95-blk-ctl: Save platform data in imx95_blk_ctl structure

* clk-allwinner:
clk: sunxi-ng: add support for the A523/T527 MCU CCU
clk: sunxi-ng: div: support power-of-two dividers
clk: sunxi-ng: sun55i-a523-ccu: Add missing NPU module clock
dt-bindings: clock: sun55i-a523-ccu: Add A523 MCU CCU clock controller
dt-bindings: clock: sun55i-a523-ccu: Add missing NPU module clock
clk: sunxi-ng: sun6i-rtc: Add A523 specifics

* clk-ti:
clk: keystone: sci-clk: use devm_kmemdup_array()
clk: ti: am33xx: keep WKUP_DEBUGSS_CLKCTRL enabled

+674 -52
+35 -2
Documentation/devicetree/bindings/clock/allwinner,sun55i-a523-ccu.yaml
··· 19 19 compatible: 20 20 enum: 21 21 - allwinner,sun55i-a523-ccu 22 + - allwinner,sun55i-a523-mcu-ccu 22 23 - allwinner,sun55i-a523-r-ccu 23 24 24 25 reg: ··· 27 26 28 27 clocks: 29 28 minItems: 4 30 - maxItems: 5 29 + maxItems: 9 31 30 32 31 clock-names: 33 32 minItems: 4 34 - maxItems: 5 33 + maxItems: 9 35 34 36 35 required: 37 36 - "#clock-cells" ··· 63 62 - const: losc 64 63 - const: iosc 65 64 - const: losc-fanout 65 + 66 + - if: 67 + properties: 68 + compatible: 69 + enum: 70 + - allwinner,sun55i-a523-mcu-ccu 71 + 72 + then: 73 + properties: 74 + clocks: 75 + items: 76 + - description: High Frequency Oscillator (usually at 24MHz) 77 + - description: Low Frequency Oscillator (usually at 32kHz) 78 + - description: Internal Oscillator 79 + - description: Audio PLL (4x) 80 + - description: Peripherals PLL 0 (300 MHz output) 81 + - description: DSP module clock 82 + - description: MBUS clock 83 + - description: PRCM AHB clock 84 + - description: PRCM APB0 clock 85 + 86 + clock-names: 87 + items: 88 + - const: hosc 89 + - const: losc 90 + - const: iosc 91 + - const: pll-audio0-4x 92 + - const: pll-periph0-300m 93 + - const: dsp 94 + - const: mbus 95 + - const: r-ahb 96 + - const: r-apb0 66 97 67 98 - if: 68 99 properties:
+28 -29
drivers/clk/imx/clk-imx95-blk-ctl.c
··· 36 36 void __iomem *base; 37 37 /* clock gate register */ 38 38 u32 clk_reg_restore; 39 + const struct imx95_blk_ctl_dev_data *pdata; 39 40 }; 40 41 41 42 struct imx95_blk_ctl_clk_dev_data { ··· 350 349 static int imx95_bc_probe(struct platform_device *pdev) 351 350 { 352 351 struct device *dev = &pdev->dev; 353 - const struct imx95_blk_ctl_dev_data *bc_data; 354 352 struct imx95_blk_ctl *bc; 355 353 struct clk_hw_onecell_data *clk_hw_data; 356 354 struct clk_hw **hws; ··· 379 379 return ret; 380 380 } 381 381 382 - bc_data = of_device_get_match_data(dev); 383 - if (!bc_data) 382 + bc->pdata = of_device_get_match_data(dev); 383 + if (!bc->pdata) 384 384 return devm_of_platform_populate(dev); 385 385 386 - clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, bc_data->num_clks), 386 + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, bc->pdata->num_clks), 387 387 GFP_KERNEL); 388 388 if (!clk_hw_data) 389 389 return -ENOMEM; 390 390 391 - if (bc_data->rpm_enabled) { 391 + if (bc->pdata->rpm_enabled) { 392 392 devm_pm_runtime_enable(&pdev->dev); 393 393 pm_runtime_resume_and_get(&pdev->dev); 394 394 } 395 395 396 - clk_hw_data->num = bc_data->num_clks; 396 + clk_hw_data->num = bc->pdata->num_clks; 397 397 hws = clk_hw_data->hws; 398 398 399 - for (i = 0; i < bc_data->num_clks; i++) { 400 - const struct imx95_blk_ctl_clk_dev_data *data = &bc_data->clk_dev_data[i]; 399 + for (i = 0; i < bc->pdata->num_clks; i++) { 400 + const struct imx95_blk_ctl_clk_dev_data *data = &bc->pdata->clk_dev_data[i]; 401 401 void __iomem *reg = base + data->reg; 402 402 403 403 if (data->type == CLK_MUX) { ··· 439 439 return 0; 440 440 441 441 cleanup: 442 - for (i = 0; i < bc_data->num_clks; i++) { 442 + for (i = 0; i < bc->pdata->num_clks; i++) { 443 443 if (IS_ERR_OR_NULL(hws[i])) 444 444 continue; 445 445 clk_hw_unregister(hws[i]); ··· 453 453 { 454 454 struct imx95_blk_ctl *bc = dev_get_drvdata(dev); 455 455 456 + bc->clk_reg_restore = readl(bc->base + bc->pdata->clk_reg_offset); 456 457 clk_disable_unprepare(bc->clk_apb); 458 + 457 459 return 0; 458 460 } 459 461 460 462 static int imx95_bc_runtime_resume(struct device *dev) 461 463 { 462 464 struct imx95_blk_ctl *bc = dev_get_drvdata(dev); 465 + int ret; 463 466 464 - return clk_prepare_enable(bc->clk_apb); 467 + ret = clk_prepare_enable(bc->clk_apb); 468 + if (ret) 469 + return ret; 470 + 471 + writel(bc->clk_reg_restore, bc->base + bc->pdata->clk_reg_offset); 472 + 473 + return 0; 465 474 } 466 475 #endif 467 476 ··· 478 469 static int imx95_bc_suspend(struct device *dev) 479 470 { 480 471 struct imx95_blk_ctl *bc = dev_get_drvdata(dev); 481 - const struct imx95_blk_ctl_dev_data *bc_data; 482 - int ret; 483 472 484 - bc_data = of_device_get_match_data(dev); 485 - if (!bc_data) 473 + if (pm_runtime_suspended(dev)) 486 474 return 0; 487 475 488 - if (bc_data->rpm_enabled) { 489 - ret = pm_runtime_get_sync(bc->dev); 490 - if (ret < 0) { 491 - pm_runtime_put_noidle(bc->dev); 492 - return ret; 493 - } 494 - } 495 - 496 - bc->clk_reg_restore = readl(bc->base + bc_data->clk_reg_offset); 476 + bc->clk_reg_restore = readl(bc->base + bc->pdata->clk_reg_offset); 477 + clk_disable_unprepare(bc->clk_apb); 497 478 498 479 return 0; 499 480 } ··· 491 492 static int imx95_bc_resume(struct device *dev) 492 493 { 493 494 struct imx95_blk_ctl *bc = dev_get_drvdata(dev); 494 - const struct imx95_blk_ctl_dev_data *bc_data; 495 + int ret; 495 496 496 - bc_data = of_device_get_match_data(dev); 497 - if (!bc_data) 497 + if (pm_runtime_suspended(dev)) 498 498 return 0; 499 499 500 - writel(bc->clk_reg_restore, bc->base + bc_data->clk_reg_offset); 500 + ret = clk_prepare_enable(bc->clk_apb); 501 + if (ret) 502 + return ret; 501 503 502 - if (bc_data->rpm_enabled) 503 - pm_runtime_put(bc->dev); 504 + writel(bc->clk_reg_restore, bc->base + bc->pdata->clk_reg_offset); 504 505 505 506 return 0; 506 507 }
+1 -4
drivers/clk/keystone/sci-clk.c
··· 480 480 num_clks++; 481 481 } 482 482 483 - provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk), 484 - GFP_KERNEL); 483 + provider->clocks = devm_kmemdup_array(dev, clks, num_clks, sizeof(sci_clk), GFP_KERNEL); 485 484 if (!provider->clocks) 486 485 return -ENOMEM; 487 - 488 - memcpy(provider->clocks, clks, num_clks * sizeof(sci_clk)); 489 486 490 487 provider->num_clocks = num_clks; 491 488
+5
drivers/clk/sunxi-ng/Kconfig
··· 57 57 default ARCH_SUNXI 58 58 depends on ARM64 || COMPILE_TEST 59 59 60 + config SUN55I_A523_MCU_CCU 61 + tristate "Support for the Allwinner A523/T527 MCU CCU" 62 + default ARCH_SUNXI 63 + depends on ARM64 || COMPILE_TEST 64 + 60 65 config SUN55I_A523_R_CCU 61 66 tristate "Support for the Allwinner A523/T527 PRCM CCU" 62 67 default ARCH_SUNXI
+2
drivers/clk/sunxi-ng/Makefile
··· 34 34 obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o 35 35 obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o 36 36 obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-ccu.o 37 + obj-$(CONFIG_SUN55I_A523_MCU_CCU) += sun55i-a523-mcu-ccu.o 37 38 obj-$(CONFIG_SUN55I_A523_R_CCU) += sun55i-a523-r-ccu.o 38 39 obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o 39 40 obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o ··· 62 61 sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o 63 62 sun50i-h616-ccu-y += ccu-sun50i-h616.o 64 63 sun55i-a523-ccu-y += ccu-sun55i-a523.o 64 + sun55i-a523-mcu-ccu-y += ccu-sun55i-a523-mcu.o 65 65 sun55i-a523-r-ccu-y += ccu-sun55i-a523-r.o 66 66 sun4i-a10-ccu-y += ccu-sun4i-a10.o 67 67 sun5i-ccu-y += ccu-sun5i.o
+469
drivers/clk/sunxi-ng/ccu-sun55i-a523-mcu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2025 Chen-Yu Tsai <wens@csie.org> 4 + * 5 + * Based on the A523 CCU driver: 6 + * Copyright (C) 2023-2024 Arm Ltd. 7 + */ 8 + 9 + #include <linux/clk-provider.h> 10 + #include <linux/io.h> 11 + #include <linux/module.h> 12 + #include <linux/platform_device.h> 13 + 14 + #include <dt-bindings/clock/sun55i-a523-mcu-ccu.h> 15 + #include <dt-bindings/reset/sun55i-a523-mcu-ccu.h> 16 + 17 + #include "ccu_common.h" 18 + #include "ccu_reset.h" 19 + 20 + #include "ccu_div.h" 21 + #include "ccu_gate.h" 22 + #include "ccu_mp.h" 23 + #include "ccu_mult.h" 24 + #include "ccu_nm.h" 25 + 26 + static const struct clk_parent_data osc24M[] = { 27 + { .fw_name = "hosc" } 28 + }; 29 + 30 + static const struct clk_parent_data ahb[] = { 31 + { .fw_name = "r-ahb" } 32 + }; 33 + 34 + static const struct clk_parent_data apb[] = { 35 + { .fw_name = "r-apb0" } 36 + }; 37 + 38 + #define SUN55I_A523_PLL_AUDIO1_REG 0x00c 39 + static struct ccu_sdm_setting pll_audio1_sdm_table[] = { 40 + { .rate = 2167603200, .pattern = 0xa000a234, .m = 1, .n = 90 }, /* div2->22.5792 */ 41 + { .rate = 2359296000, .pattern = 0xa0009ba6, .m = 1, .n = 98 }, /* div2->24.576 */ 42 + { .rate = 1806336000, .pattern = 0xa000872b, .m = 1, .n = 75 }, /* div5->22.576 */ 43 + }; 44 + 45 + static struct ccu_nm pll_audio1_clk = { 46 + .enable = BIT(27), 47 + .lock = BIT(28), 48 + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), 49 + .m = _SUNXI_CCU_DIV(1, 1), 50 + .sdm = _SUNXI_CCU_SDM(pll_audio1_sdm_table, BIT(24), 51 + 0x010, BIT(31)), 52 + .min_rate = 180000000U, 53 + .max_rate = 3500000000U, 54 + .common = { 55 + .reg = 0x00c, 56 + .features = CCU_FEATURE_SIGMA_DELTA_MOD, 57 + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-audio1", 58 + osc24M, &ccu_nm_ops, 59 + CLK_SET_RATE_GATE), 60 + }, 61 + }; 62 + 63 + /* 64 + * /2 and /5 dividers are actually programmable, but we just use the 65 + * values from the BSP, since the audio PLL only needs to provide a 66 + * couple clock rates. This also matches the names given in the manual. 67 + */ 68 + static const struct clk_hw *pll_audio1_div_parents[] = { &pll_audio1_clk.common.hw }; 69 + static CLK_FIXED_FACTOR_HWS(pll_audio1_div2_clk, "pll-audio1-div2", 70 + pll_audio1_div_parents, 2, 1, 71 + CLK_SET_RATE_PARENT); 72 + static CLK_FIXED_FACTOR_HWS(pll_audio1_div5_clk, "pll-audio1-div5", 73 + pll_audio1_div_parents, 5, 1, 74 + CLK_SET_RATE_PARENT); 75 + 76 + static SUNXI_CCU_M_WITH_GATE(audio_out_clk, "audio-out", 77 + "pll-audio1-div2", 0x01c, 78 + 0, 5, BIT(31), CLK_SET_RATE_PARENT); 79 + 80 + static const struct clk_parent_data dsp_parents[] = { 81 + { .fw_name = "hosc" }, 82 + { .fw_name = "losc" }, 83 + { .fw_name = "iosc" }, 84 + /* 85 + * The order of the following two parent is from the BSP code. It is 86 + * the opposite in the manual. Testing with the DSP is required to 87 + * figure out the real order. 88 + */ 89 + { .hw = &pll_audio1_div5_clk.hw }, 90 + { .hw = &pll_audio1_div2_clk.hw }, 91 + { .fw_name = "dsp" }, 92 + }; 93 + static SUNXI_CCU_M_DATA_WITH_MUX_GATE(dsp_clk, "mcu-dsp", dsp_parents, 0x0020, 94 + 0, 5, /* M */ 95 + 24, 3, /* mux */ 96 + BIT(31), /* gate */ 97 + 0); 98 + 99 + static const struct clk_parent_data i2s_parents[] = { 100 + { .fw_name = "pll-audio0-4x" }, 101 + { .hw = &pll_audio1_div2_clk.hw }, 102 + { .hw = &pll_audio1_div5_clk.hw }, 103 + }; 104 + 105 + static SUNXI_CCU_DUALDIV_MUX_GATE(i2s0_clk, "i2s0", i2s_parents, 0x02c, 106 + 0, 5, /* M */ 107 + 5, 5, /* P */ 108 + 24, 3, /* mux */ 109 + BIT(31), /* gate */ 110 + CLK_SET_RATE_PARENT); 111 + static SUNXI_CCU_DUALDIV_MUX_GATE(i2s1_clk, "i2s1", i2s_parents, 0x030, 112 + 0, 5, /* M */ 113 + 5, 5, /* P */ 114 + 24, 3, /* mux */ 115 + BIT(31), /* gate */ 116 + CLK_SET_RATE_PARENT); 117 + static SUNXI_CCU_DUALDIV_MUX_GATE(i2s2_clk, "i2s2", i2s_parents, 0x034, 118 + 0, 5, /* M */ 119 + 5, 5, /* P */ 120 + 24, 3, /* mux */ 121 + BIT(31), /* gate */ 122 + CLK_SET_RATE_PARENT); 123 + static SUNXI_CCU_DUALDIV_MUX_GATE(i2s3_clk, "i2s3", i2s_parents, 0x038, 124 + 0, 5, /* M */ 125 + 5, 5, /* P */ 126 + 24, 3, /* mux */ 127 + BIT(31), /* gate */ 128 + CLK_SET_RATE_PARENT); 129 + 130 + static const struct clk_parent_data i2s3_asrc_parents[] = { 131 + { .fw_name = "pll-periph0-300m" }, 132 + { .hw = &pll_audio1_div2_clk.hw }, 133 + { .hw = &pll_audio1_div5_clk.hw }, 134 + }; 135 + static SUNXI_CCU_DUALDIV_MUX_GATE(i2s3_asrc_clk, "i2s3-asrc", 136 + i2s3_asrc_parents, 0x03c, 137 + 0, 5, /* M */ 138 + 5, 5, /* P */ 139 + 24, 3, /* mux */ 140 + BIT(31), /* gate */ 141 + CLK_SET_RATE_PARENT); 142 + 143 + static SUNXI_CCU_GATE_DATA(bus_i2s0_clk, "bus-i2s0", apb, 0x040, BIT(0), 0); 144 + static SUNXI_CCU_GATE_DATA(bus_i2s1_clk, "bus-i2s1", apb, 0x040, BIT(1), 0); 145 + static SUNXI_CCU_GATE_DATA(bus_i2s2_clk, "bus-i2s2", apb, 0x040, BIT(2), 0); 146 + static SUNXI_CCU_GATE_DATA(bus_i2s3_clk, "bus-i2s3", apb, 0x040, BIT(3), 0); 147 + 148 + static const struct clk_parent_data audio_parents[] = { 149 + { .fw_name = "pll-audio0-4x" }, 150 + { .hw = &pll_audio1_div2_clk.hw }, 151 + { .hw = &pll_audio1_div5_clk.hw }, 152 + }; 153 + static SUNXI_CCU_DUALDIV_MUX_GATE(spdif_tx_clk, "spdif-tx", 154 + audio_parents, 0x044, 155 + 0, 5, /* M */ 156 + 5, 5, /* P */ 157 + 24, 3, /* mux */ 158 + BIT(31), /* gate */ 159 + CLK_SET_RATE_PARENT); 160 + static SUNXI_CCU_DUALDIV_MUX_GATE(spdif_rx_clk, "spdif-rx", 161 + i2s3_asrc_parents, 0x048, 162 + 0, 5, /* M */ 163 + 5, 5, /* P */ 164 + 24, 3, /* mux */ 165 + BIT(31), /* gate */ 166 + CLK_SET_RATE_PARENT); 167 + 168 + static SUNXI_CCU_GATE_DATA(bus_spdif_clk, "bus-spdif", apb, 0x04c, BIT(0), 0); 169 + 170 + static SUNXI_CCU_DUALDIV_MUX_GATE(dmic_clk, "dmic", audio_parents, 0x050, 171 + 0, 5, /* M */ 172 + 5, 5, /* P */ 173 + 24, 3, /* mux */ 174 + BIT(31), /* gate */ 175 + CLK_SET_RATE_PARENT); 176 + 177 + static SUNXI_CCU_GATE_DATA(bus_dmic_clk, "bus-dmic", apb, 0x054, BIT(0), 0); 178 + 179 + static SUNXI_CCU_DUALDIV_MUX_GATE(audio_dac_clk, "audio-dac", 180 + audio_parents, 0x058, 181 + 0, 5, /* M */ 182 + 5, 5, /* P */ 183 + 24, 3, /* mux */ 184 + BIT(31), /* gate */ 185 + CLK_SET_RATE_PARENT); 186 + static SUNXI_CCU_DUALDIV_MUX_GATE(audio_adc_clk, "audio-adc", 187 + audio_parents, 0x05c, 188 + 0, 5, /* M */ 189 + 5, 5, /* P */ 190 + 24, 3, /* mux */ 191 + BIT(31), /* gate */ 192 + CLK_SET_RATE_PARENT); 193 + 194 + static SUNXI_CCU_GATE_DATA(bus_audio_codec_clk, "bus-audio-codec", 195 + apb, 0x060, BIT(0), 0); 196 + 197 + static SUNXI_CCU_GATE_DATA(bus_dsp_msgbox_clk, "bus-dsp-msgbox", 198 + ahb, 0x068, BIT(0), 0); 199 + static SUNXI_CCU_GATE_DATA(bus_dsp_cfg_clk, "bus-dsp-cfg", 200 + apb, 0x06c, BIT(0), 0); 201 + 202 + static SUNXI_CCU_GATE_DATA(bus_npu_hclk, "bus-npu-hclk", ahb, 0x070, BIT(1), 0); 203 + static SUNXI_CCU_GATE_DATA(bus_npu_aclk, "bus-npu-aclk", ahb, 0x070, BIT(2), 0); 204 + 205 + static const struct clk_parent_data timer_parents[] = { 206 + { .fw_name = "hosc" }, 207 + { .fw_name = "losc" }, 208 + { .fw_name = "iosc" }, 209 + { .fw_name = "r-ahb" } 210 + }; 211 + static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer0_clk, "mcu-timer0", timer_parents, 212 + 0x074, 213 + 1, 3, /* P */ 214 + 4, 2, /* mux */ 215 + BIT(0), /* gate */ 216 + 0); 217 + static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer1_clk, "mcu-timer1", timer_parents, 218 + 0x078, 219 + 1, 3, /* P */ 220 + 4, 2, /* mux */ 221 + BIT(0), /* gate */ 222 + 0); 223 + static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer2_clk, "mcu-timer2", timer_parents, 224 + 0x07c, 225 + 1, 3, /* P */ 226 + 4, 2, /* mux */ 227 + BIT(0), /* gate */ 228 + 0); 229 + static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer3_clk, "mcu-timer3", timer_parents, 230 + 0x080, 231 + 1, 3, /* P */ 232 + 4, 2, /* mux */ 233 + BIT(0), /* gate */ 234 + 0); 235 + static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer4_clk, "mcu-timer4", timer_parents, 236 + 0x084, 237 + 1, 3, /* P */ 238 + 4, 2, /* mux */ 239 + BIT(0), /* gate */ 240 + 0); 241 + static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer5_clk, "mcu-timer5", timer_parents, 242 + 0x088, 243 + 1, 3, /* P */ 244 + 4, 2, /* mux */ 245 + BIT(0), /* gate */ 246 + 0); 247 + static SUNXI_CCU_GATE_DATA(bus_mcu_timer_clk, "bus-mcu-timer", ahb, 0x08c, BIT(0), 0); 248 + static SUNXI_CCU_GATE_DATA(bus_mcu_dma_clk, "bus-mcu-dma", ahb, 0x104, BIT(0), 0); 249 + /* tzma* only found in BSP code. */ 250 + static SUNXI_CCU_GATE_DATA(tzma0_clk, "tzma0", ahb, 0x108, BIT(0), 0); 251 + static SUNXI_CCU_GATE_DATA(tzma1_clk, "tzma1", ahb, 0x10c, BIT(0), 0); 252 + /* parent is a guess as this block is not shown in the system bus tree diagram */ 253 + static SUNXI_CCU_GATE_DATA(bus_pubsram_clk, "bus-pubsram", ahb, 0x114, BIT(0), 0); 254 + 255 + /* 256 + * user manual has "mbus" clock as parent of both clocks below, 257 + * but this makes more sense, since BSP MCU DMA controller has 258 + * reference to both of them, likely needing both enabled. 259 + */ 260 + static SUNXI_CCU_GATE_FW(mbus_mcu_clk, "mbus-mcu", "mbus", 0x11c, BIT(1), 0); 261 + static SUNXI_CCU_GATE_HW(mbus_mcu_dma_clk, "mbus-mcu-dma", 262 + &mbus_mcu_clk.common.hw, 0x11c, BIT(0), 0); 263 + 264 + static const struct clk_parent_data riscv_pwm_parents[] = { 265 + { .fw_name = "hosc" }, 266 + { .fw_name = "losc" }, 267 + { .fw_name = "iosc" }, 268 + }; 269 + 270 + static SUNXI_CCU_MUX_DATA_WITH_GATE(riscv_clk, "riscv", 271 + riscv_pwm_parents, 0x120, 272 + 27, 3, BIT(31), 0); 273 + /* Parents are guesses as these two blocks are not shown in the system bus tree diagram */ 274 + static SUNXI_CCU_GATE_DATA(bus_riscv_cfg_clk, "bus-riscv-cfg", ahb, 275 + 0x124, BIT(0), 0); 276 + static SUNXI_CCU_GATE_DATA(bus_riscv_msgbox_clk, "bus-riscv-msgbox", ahb, 277 + 0x128, BIT(0), 0); 278 + 279 + static SUNXI_CCU_MUX_DATA_WITH_GATE(mcu_pwm0_clk, "mcu-pwm0", 280 + riscv_pwm_parents, 0x130, 281 + 24, 3, BIT(31), 0); 282 + static SUNXI_CCU_GATE_DATA(bus_mcu_pwm0_clk, "bus-mcu-pwm0", apb, 283 + 0x134, BIT(0), 0); 284 + 285 + /* 286 + * Contains all clocks that are controlled by a hardware register. They 287 + * have a (sunxi) .common member, which needs to be initialised by the common 288 + * sunxi CCU code, to be filled with the MMIO base address and the shared lock. 289 + */ 290 + static struct ccu_common *sun55i_a523_mcu_ccu_clks[] = { 291 + &pll_audio1_clk.common, 292 + &audio_out_clk.common, 293 + &dsp_clk.common, 294 + &i2s0_clk.common, 295 + &i2s1_clk.common, 296 + &i2s2_clk.common, 297 + &i2s3_clk.common, 298 + &i2s3_asrc_clk.common, 299 + &bus_i2s0_clk.common, 300 + &bus_i2s1_clk.common, 301 + &bus_i2s2_clk.common, 302 + &bus_i2s3_clk.common, 303 + &spdif_tx_clk.common, 304 + &spdif_rx_clk.common, 305 + &bus_spdif_clk.common, 306 + &dmic_clk.common, 307 + &bus_dmic_clk.common, 308 + &audio_dac_clk.common, 309 + &audio_adc_clk.common, 310 + &bus_audio_codec_clk.common, 311 + &bus_dsp_msgbox_clk.common, 312 + &bus_dsp_cfg_clk.common, 313 + &bus_npu_aclk.common, 314 + &bus_npu_hclk.common, 315 + &mcu_timer0_clk.common, 316 + &mcu_timer1_clk.common, 317 + &mcu_timer2_clk.common, 318 + &mcu_timer3_clk.common, 319 + &mcu_timer4_clk.common, 320 + &mcu_timer5_clk.common, 321 + &bus_mcu_timer_clk.common, 322 + &bus_mcu_dma_clk.common, 323 + &tzma0_clk.common, 324 + &tzma1_clk.common, 325 + &bus_pubsram_clk.common, 326 + &mbus_mcu_dma_clk.common, 327 + &mbus_mcu_clk.common, 328 + &riscv_clk.common, 329 + &bus_riscv_cfg_clk.common, 330 + &bus_riscv_msgbox_clk.common, 331 + &mcu_pwm0_clk.common, 332 + &bus_mcu_pwm0_clk.common, 333 + }; 334 + 335 + static struct clk_hw_onecell_data sun55i_a523_mcu_hw_clks = { 336 + .hws = { 337 + [CLK_MCU_PLL_AUDIO1] = &pll_audio1_clk.common.hw, 338 + [CLK_MCU_PLL_AUDIO1_DIV2] = &pll_audio1_div2_clk.hw, 339 + [CLK_MCU_PLL_AUDIO1_DIV5] = &pll_audio1_div5_clk.hw, 340 + [CLK_MCU_AUDIO_OUT] = &audio_out_clk.common.hw, 341 + [CLK_MCU_DSP] = &dsp_clk.common.hw, 342 + [CLK_MCU_I2S0] = &i2s0_clk.common.hw, 343 + [CLK_MCU_I2S1] = &i2s1_clk.common.hw, 344 + [CLK_MCU_I2S2] = &i2s2_clk.common.hw, 345 + [CLK_MCU_I2S3] = &i2s3_clk.common.hw, 346 + [CLK_MCU_I2S3_ASRC] = &i2s3_asrc_clk.common.hw, 347 + [CLK_BUS_MCU_I2S0] = &bus_i2s0_clk.common.hw, 348 + [CLK_BUS_MCU_I2S1] = &bus_i2s1_clk.common.hw, 349 + [CLK_BUS_MCU_I2S2] = &bus_i2s2_clk.common.hw, 350 + [CLK_BUS_MCU_I2S3] = &bus_i2s3_clk.common.hw, 351 + [CLK_MCU_SPDIF_TX] = &spdif_tx_clk.common.hw, 352 + [CLK_MCU_SPDIF_RX] = &spdif_rx_clk.common.hw, 353 + [CLK_BUS_MCU_SPDIF] = &bus_spdif_clk.common.hw, 354 + [CLK_MCU_DMIC] = &dmic_clk.common.hw, 355 + [CLK_BUS_MCU_DMIC] = &bus_dmic_clk.common.hw, 356 + [CLK_MCU_AUDIO_CODEC_DAC] = &audio_dac_clk.common.hw, 357 + [CLK_MCU_AUDIO_CODEC_ADC] = &audio_adc_clk.common.hw, 358 + [CLK_BUS_MCU_AUDIO_CODEC] = &bus_audio_codec_clk.common.hw, 359 + [CLK_BUS_MCU_DSP_MSGBOX] = &bus_dsp_msgbox_clk.common.hw, 360 + [CLK_BUS_MCU_DSP_CFG] = &bus_dsp_cfg_clk.common.hw, 361 + [CLK_BUS_MCU_NPU_HCLK] = &bus_npu_hclk.common.hw, 362 + [CLK_BUS_MCU_NPU_ACLK] = &bus_npu_aclk.common.hw, 363 + [CLK_MCU_TIMER0] = &mcu_timer0_clk.common.hw, 364 + [CLK_MCU_TIMER1] = &mcu_timer1_clk.common.hw, 365 + [CLK_MCU_TIMER2] = &mcu_timer2_clk.common.hw, 366 + [CLK_MCU_TIMER3] = &mcu_timer3_clk.common.hw, 367 + [CLK_MCU_TIMER4] = &mcu_timer4_clk.common.hw, 368 + [CLK_MCU_TIMER5] = &mcu_timer5_clk.common.hw, 369 + [CLK_BUS_MCU_TIMER] = &bus_mcu_timer_clk.common.hw, 370 + [CLK_BUS_MCU_DMA] = &bus_mcu_dma_clk.common.hw, 371 + [CLK_MCU_TZMA0] = &tzma0_clk.common.hw, 372 + [CLK_MCU_TZMA1] = &tzma1_clk.common.hw, 373 + [CLK_BUS_MCU_PUBSRAM] = &bus_pubsram_clk.common.hw, 374 + [CLK_MCU_MBUS_DMA] = &mbus_mcu_dma_clk.common.hw, 375 + [CLK_MCU_MBUS] = &mbus_mcu_clk.common.hw, 376 + [CLK_MCU_RISCV] = &riscv_clk.common.hw, 377 + [CLK_BUS_MCU_RISCV_CFG] = &bus_riscv_cfg_clk.common.hw, 378 + [CLK_BUS_MCU_RISCV_MSGBOX] = &bus_riscv_msgbox_clk.common.hw, 379 + [CLK_MCU_PWM0] = &mcu_pwm0_clk.common.hw, 380 + [CLK_BUS_MCU_PWM0] = &bus_mcu_pwm0_clk.common.hw, 381 + }, 382 + .num = CLK_BUS_MCU_PWM0 + 1, 383 + }; 384 + 385 + static struct ccu_reset_map sun55i_a523_mcu_ccu_resets[] = { 386 + [RST_BUS_MCU_I2S0] = { 0x0040, BIT(16) }, 387 + [RST_BUS_MCU_I2S1] = { 0x0040, BIT(17) }, 388 + [RST_BUS_MCU_I2S2] = { 0x0040, BIT(18) }, 389 + [RST_BUS_MCU_I2S3] = { 0x0040, BIT(19) }, 390 + [RST_BUS_MCU_SPDIF] = { 0x004c, BIT(16) }, 391 + [RST_BUS_MCU_DMIC] = { 0x0054, BIT(16) }, 392 + [RST_BUS_MCU_AUDIO_CODEC] = { 0x0060, BIT(16) }, 393 + [RST_BUS_MCU_DSP_MSGBOX] = { 0x0068, BIT(16) }, 394 + [RST_BUS_MCU_DSP_CFG] = { 0x006c, BIT(16) }, 395 + [RST_BUS_MCU_NPU] = { 0x0070, BIT(16) }, 396 + [RST_BUS_MCU_TIMER] = { 0x008c, BIT(16) }, 397 + /* dsp and dsp_debug resets only found in BSP code. */ 398 + [RST_BUS_MCU_DSP_DEBUG] = { 0x0100, BIT(16) }, 399 + [RST_BUS_MCU_DSP] = { 0x0100, BIT(17) }, 400 + [RST_BUS_MCU_DMA] = { 0x0104, BIT(16) }, 401 + [RST_BUS_MCU_PUBSRAM] = { 0x0114, BIT(16) }, 402 + [RST_BUS_MCU_RISCV_CFG] = { 0x0124, BIT(16) }, 403 + [RST_BUS_MCU_RISCV_DEBUG] = { 0x0124, BIT(17) }, 404 + [RST_BUS_MCU_RISCV_CORE] = { 0x0124, BIT(18) }, 405 + [RST_BUS_MCU_RISCV_MSGBOX] = { 0x0128, BIT(16) }, 406 + [RST_BUS_MCU_PWM0] = { 0x0134, BIT(16) }, 407 + }; 408 + 409 + static const struct sunxi_ccu_desc sun55i_a523_mcu_ccu_desc = { 410 + .ccu_clks = sun55i_a523_mcu_ccu_clks, 411 + .num_ccu_clks = ARRAY_SIZE(sun55i_a523_mcu_ccu_clks), 412 + 413 + .hw_clks = &sun55i_a523_mcu_hw_clks, 414 + 415 + .resets = sun55i_a523_mcu_ccu_resets, 416 + .num_resets = ARRAY_SIZE(sun55i_a523_mcu_ccu_resets), 417 + }; 418 + 419 + static int sun55i_a523_mcu_ccu_probe(struct platform_device *pdev) 420 + { 421 + void __iomem *reg; 422 + u32 val; 423 + int ret; 424 + 425 + reg = devm_platform_ioremap_resource(pdev, 0); 426 + if (IS_ERR(reg)) 427 + return PTR_ERR(reg); 428 + 429 + val = readl(reg + SUN55I_A523_PLL_AUDIO1_REG); 430 + 431 + /* 432 + * The PLL clock code does not model all bits, for instance it does 433 + * not support a separate enable and gate bit. We present the 434 + * gate bit(27) as the enable bit, but then have to set the 435 + * PLL Enable, LDO Enable, and Lock Enable bits on all PLLs here. 436 + */ 437 + val |= BIT(31) | BIT(30) | BIT(29); 438 + 439 + /* Enforce p1 = 5, p0 = 2 (the default) for PLL_AUDIO1 */ 440 + val &= ~(GENMASK(22, 20) | GENMASK(18, 16)); 441 + val |= (4 << 20) | (1 << 16); 442 + 443 + writel(val, reg + SUN55I_A523_PLL_AUDIO1_REG); 444 + 445 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun55i_a523_mcu_ccu_desc); 446 + if (ret) 447 + return ret; 448 + 449 + return 0; 450 + } 451 + 452 + static const struct of_device_id sun55i_a523_mcu_ccu_ids[] = { 453 + { .compatible = "allwinner,sun55i-a523-mcu-ccu" }, 454 + { } 455 + }; 456 + 457 + static struct platform_driver sun55i_a523_mcu_ccu_driver = { 458 + .probe = sun55i_a523_mcu_ccu_probe, 459 + .driver = { 460 + .name = "sun55i-a523-mcu-ccu", 461 + .suppress_bind_attrs = true, 462 + .of_match_table = sun55i_a523_mcu_ccu_ids, 463 + }, 464 + }; 465 + module_platform_driver(sun55i_a523_mcu_ccu_driver); 466 + 467 + MODULE_IMPORT_NS("SUNXI_CCU"); 468 + MODULE_DESCRIPTION("Support for the Allwinner A523 MCU CCU"); 469 + MODULE_LICENSE("GPL");
+18 -3
drivers/clk/sunxi-ng/ccu-sun55i-a523.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/platform_device.h> 13 13 14 + #include <dt-bindings/clock/sun55i-a523-ccu.h> 15 + #include <dt-bindings/reset/sun55i-a523-ccu.h> 16 + 14 17 #include "../clk.h" 15 18 16 19 #include "ccu_common.h" ··· 27 24 #include "ccu_nkm.h" 28 25 #include "ccu_nkmp.h" 29 26 #include "ccu_nm.h" 30 - 31 - #include "ccu-sun55i-a523.h" 32 27 33 28 /* 34 29 * The 24 MHz oscillator, the root of most of the clock tree. ··· 486 485 CLK_SET_RATE_PARENT); 487 486 488 487 static SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", ahb_hws, 0x69c, BIT(0), 0); 488 + 489 + static const struct clk_hw *npu_parents[] = { 490 + &pll_periph0_480M_clk.common.hw, 491 + &pll_periph0_600M_clk.hw, 492 + &pll_periph0_800M_clk.common.hw, 493 + &pll_npu_2x_clk.hw, 494 + }; 495 + static SUNXI_CCU_M_HW_WITH_MUX_GATE(npu_clk, "npu", npu_parents, 0x6e0, 496 + 0, 5, /* M */ 497 + 24, 3, /* mux */ 498 + BIT(31), /* gate */ 499 + CLK_SET_RATE_PARENT); 489 500 490 501 static SUNXI_CCU_GATE_HWS(bus_dma_clk, "bus-dma", ahb_hws, 0x70c, BIT(0), 0); 491 502 ··· 1230 1217 &bus_ce_sys_clk.common, 1231 1218 &ve_clk.common, 1232 1219 &bus_ve_clk.common, 1220 + &npu_clk.common, 1233 1221 &bus_dma_clk.common, 1234 1222 &bus_msgbox_clk.common, 1235 1223 &bus_spinlock_clk.common, ··· 1357 1343 }; 1358 1344 1359 1345 static struct clk_hw_onecell_data sun55i_a523_hw_clks = { 1360 - .num = CLK_NUMBER, 1361 1346 .hws = { 1362 1347 [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw, 1363 1348 [CLK_PLL_PERIPH0_4X] = &pll_periph0_4x_clk.common.hw, ··· 1537 1524 [CLK_FANOUT0] = &fanout0_clk.common.hw, 1538 1525 [CLK_FANOUT1] = &fanout1_clk.common.hw, 1539 1526 [CLK_FANOUT2] = &fanout2_clk.common.hw, 1527 + [CLK_NPU] = &npu_clk.common.hw, 1540 1528 }, 1529 + .num = CLK_NPU + 1, 1541 1530 }; 1542 1531 1543 1532 static struct ccu_reset_map sun55i_a523_ccu_resets[] = {
-14
drivers/clk/sunxi-ng/ccu-sun55i-a523.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * Copyright 2024 Arm Ltd. 4 - */ 5 - 6 - #ifndef _CCU_SUN55I_A523_H 7 - #define _CCU_SUN55I_A523_H 8 - 9 - #include <dt-bindings/clock/sun55i-a523-ccu.h> 10 - #include <dt-bindings/reset/sun55i-a523-ccu.h> 11 - 12 - #define CLK_NUMBER (CLK_FANOUT2 + 1) 13 - 14 - #endif /* _CCU_SUN55I_A523_H */
+11
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
··· 325 325 .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), 326 326 }; 327 327 328 + static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = { 329 + .have_ext_osc32k = true, 330 + .have_iosc_calibration = true, 331 + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, 332 + .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), 333 + }; 334 + 328 335 static const struct of_device_id sun6i_rtc_ccu_match[] = { 329 336 { 330 337 .compatible = "allwinner,sun50i-h616-rtc", ··· 340 333 { 341 334 .compatible = "allwinner,sun50i-r329-rtc", 342 335 .data = &sun50i_r329_rtc_ccu_data, 336 + }, 337 + { 338 + .compatible = "allwinner,sun55i-a523-rtc", 339 + .data = &sun55i_a523_rtc_ccu_data, 343 340 }, 344 341 {}, 345 342 };
+18
drivers/clk/sunxi-ng/ccu_div.h
··· 274 274 SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \ 275 275 _mshift, _mwidth, 0, _flags) 276 276 277 + #define SUNXI_CCU_P_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 278 + _mshift, _mwidth, \ 279 + _muxshift, _muxwidth, \ 280 + _gate, _flags) \ 281 + struct ccu_div _struct = { \ 282 + .enable = _gate, \ 283 + .div = _SUNXI_CCU_DIV_FLAGS(_mshift, _mwidth, \ 284 + CLK_DIVIDER_POWER_OF_TWO), \ 285 + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ 286 + .common = { \ 287 + .reg = _reg, \ 288 + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ 289 + _parents, \ 290 + &ccu_div_ops, \ 291 + _flags), \ 292 + }, \ 293 + } 294 + 277 295 static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw) 278 296 { 279 297 struct ccu_common *common = hw_to_ccu_common(hw);
+2
drivers/clk/ti/clk-33xx.c
··· 258 258 "dpll_ddr_m2_ck", 259 259 "dpll_mpu_m2_ck", 260 260 "l3_gclk", 261 + /* WKUP_DEBUGSS_CLKCTRL - disable fails, AM335x Errata Advisory 1.0.42 */ 262 + "l3-aon-clkctrl:0000:0", 261 263 /* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */ 262 264 "l3-clkctrl:00bc:0", 263 265 "l4hs_gclk",
+1
include/dt-bindings/clock/sun55i-a523-ccu.h
··· 185 185 #define CLK_FANOUT0 176 186 186 #define CLK_FANOUT1 177 187 187 #define CLK_FANOUT2 178 188 + #define CLK_NPU 179 188 189 189 190 #endif /* _DT_BINDINGS_CLK_SUN55I_A523_CCU_H_ */
+54
include/dt-bindings/clock/sun55i-a523-mcu-ccu.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ 2 + /* 3 + * Copyright (C) 2025 Chen-Yu Tsai <wens@csie.org> 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_CLK_SUN55I_A523_MCU_CCU_H_ 7 + #define _DT_BINDINGS_CLK_SUN55I_A523_MCU_CCU_H_ 8 + 9 + #define CLK_MCU_PLL_AUDIO1 0 10 + #define CLK_MCU_PLL_AUDIO1_DIV2 1 11 + #define CLK_MCU_PLL_AUDIO1_DIV5 2 12 + #define CLK_MCU_AUDIO_OUT 3 13 + #define CLK_MCU_DSP 4 14 + #define CLK_MCU_I2S0 5 15 + #define CLK_MCU_I2S1 6 16 + #define CLK_MCU_I2S2 7 17 + #define CLK_MCU_I2S3 8 18 + #define CLK_MCU_I2S3_ASRC 9 19 + #define CLK_BUS_MCU_I2S0 10 20 + #define CLK_BUS_MCU_I2S1 11 21 + #define CLK_BUS_MCU_I2S2 12 22 + #define CLK_BUS_MCU_I2S3 13 23 + #define CLK_MCU_SPDIF_TX 14 24 + #define CLK_MCU_SPDIF_RX 15 25 + #define CLK_BUS_MCU_SPDIF 16 26 + #define CLK_MCU_DMIC 17 27 + #define CLK_BUS_MCU_DMIC 18 28 + #define CLK_MCU_AUDIO_CODEC_DAC 19 29 + #define CLK_MCU_AUDIO_CODEC_ADC 20 30 + #define CLK_BUS_MCU_AUDIO_CODEC 21 31 + #define CLK_BUS_MCU_DSP_MSGBOX 22 32 + #define CLK_BUS_MCU_DSP_CFG 23 33 + #define CLK_BUS_MCU_NPU_HCLK 24 34 + #define CLK_BUS_MCU_NPU_ACLK 25 35 + #define CLK_MCU_TIMER0 26 36 + #define CLK_MCU_TIMER1 27 37 + #define CLK_MCU_TIMER2 28 38 + #define CLK_MCU_TIMER3 29 39 + #define CLK_MCU_TIMER4 30 40 + #define CLK_MCU_TIMER5 31 41 + #define CLK_BUS_MCU_TIMER 32 42 + #define CLK_BUS_MCU_DMA 33 43 + #define CLK_MCU_TZMA0 34 44 + #define CLK_MCU_TZMA1 35 45 + #define CLK_BUS_MCU_PUBSRAM 36 46 + #define CLK_MCU_MBUS_DMA 37 47 + #define CLK_MCU_MBUS 38 48 + #define CLK_MCU_RISCV 39 49 + #define CLK_BUS_MCU_RISCV_CFG 40 50 + #define CLK_BUS_MCU_RISCV_MSGBOX 41 51 + #define CLK_MCU_PWM0 42 52 + #define CLK_BUS_MCU_PWM0 43 53 + 54 + #endif /* _DT_BINDINGS_CLK_SUN55I_A523_MCU_CCU_H_ */
+30
include/dt-bindings/reset/sun55i-a523-mcu-ccu.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ 2 + /* 3 + * Copyright (C) 2025 Chen-Yu Tsai <wens@csie.org> 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_RST_SUN55I_A523_MCU_CCU_H_ 7 + #define _DT_BINDINGS_RST_SUN55I_A523_MCU_CCU_H_ 8 + 9 + #define RST_BUS_MCU_I2S0 0 10 + #define RST_BUS_MCU_I2S1 1 11 + #define RST_BUS_MCU_I2S2 2 12 + #define RST_BUS_MCU_I2S3 3 13 + #define RST_BUS_MCU_SPDIF 4 14 + #define RST_BUS_MCU_DMIC 5 15 + #define RST_BUS_MCU_AUDIO_CODEC 6 16 + #define RST_BUS_MCU_DSP_MSGBOX 7 17 + #define RST_BUS_MCU_DSP_CFG 8 18 + #define RST_BUS_MCU_NPU 9 19 + #define RST_BUS_MCU_TIMER 10 20 + #define RST_BUS_MCU_DSP_DEBUG 11 21 + #define RST_BUS_MCU_DSP 12 22 + #define RST_BUS_MCU_DMA 13 23 + #define RST_BUS_MCU_PUBSRAM 14 24 + #define RST_BUS_MCU_RISCV_CFG 15 25 + #define RST_BUS_MCU_RISCV_DEBUG 16 26 + #define RST_BUS_MCU_RISCV_CORE 17 27 + #define RST_BUS_MCU_RISCV_MSGBOX 18 28 + #define RST_BUS_MCU_PWM0 19 29 + 30 + #endif /* _DT_BINDINGS_RST_SUN55I_A523_MCU_CCU_H_ */