diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-05 10:43:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-05 10:43:32 -0700 |
commit | 347619565197ae0e62a755efc4a80904d66fc0a1 (patch) | |
tree | b2b219d59acec3ec1735e7e598362a3420f193b6 /drivers/clk | |
parent | aa1a8ce533324d12696a9f4b71dbc5eb561a2e04 (diff) | |
parent | 28ecaf1c30fe3f616eef5ab2dd5990399957234e (diff) |
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd:
"There's not much to see in the core framework this time around.
Instead the majority of the diff is the normal collection of driver
additions for new SoCs and non-critical clk data fixes and updates.
The framework must be middle aged.
The two biggest directories in the diffstat show that the Qualcomm and
Unisoc support added a handful of big drivers for new SoCs but that's
not really the whole story because those new drivers tend to add large
numbers of lines of clk data. There's a handful of AT91 clk drivers
added this time around too and a bunch of improvements to drivers like
the i.MX driver. All around lots of updates and fixes in various clk
drivers which is good to see.
The core framework has only one real major change which has been
baking in next for the past couple months. It fixes the framework so
that it stops caching a clk's phase when the phase clk_op returns an
error. Before this change we would consider some negative errno as a
phase and that just doesn't make sense.
Core:
- Don't show clk phase when it is invalid
New Drivers:
- Add support for Unisoc SC9863A clks
- Qualcomm SM8250 RPMh and MSM8976 RPM clks
- Qualcomm SM8250 Global Clock Controller (GCC) support
- Qualcomm SC7180 Modem Clock Controller (MSS CC) support
- EHRPWM's TimeBase clock(TBCLK) for TI AM654 SoCs
- Support PMC clks on at91sam9n12, at91rm9200, sama5d3, and
at91sam9g45 SoCs
Updates:
- GPU GX GDSC support on Qualcomm sc7180
- Fixes and improvements for the Marvell MMP2/MMP3 SoC clk drivers
- A series from Anson to convert i.MX8 clock bindings to json-schema
- Update i.MX pll14xx driver to include new frequency entries for
pll1443x table, and return error for invalid PLL type
- Add missing of_node_put() call for a number of i.MX clock drivers
- Drop flag CLK_IS_CRITICAL from 'A53_CORE' mux clock, as we already
have the flag on its child cpu clock
- Fix a53 cpu clock for i.MX8 drivers to get it source from ARM PLL
via CORE_SEL slice, and source from A53 CCM clk root when we need
to change ARM PLL frequency. Thus, we can support core running
above 1GHz safely
- Update i.MX pfdv2 driver to check zero rate and use determine_rate
for getting the best rate
- Add CLKO2 for imx8mm, SNVS clock for imx8mn, and PXP clock for
imx7d
- Remove PMC clks from Tegra clk driver
- Improved clock/reset handling for the Renesas R-Car USB2 Clock
Selector
- Conversion to json-schema of the Renesas CPG/MSSR DT bindings
- Add Crypto clocks on Renesas R-Car M3-W/W+, M3-N, E3, and D3
- Add RPC (QSPI/HyperFLASH) clocks on Renesas R-Car H3, M3-W/W+, and
M3-N
- Update Amlogic audio clock gate hierarchy for meson8 and gxbb
- Update Amlogic g12a spicc clock sources
- Support for Ingenic X1000 TCU clks"
* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (146 commits)
clk: sprd: fix to get a correct ibias of pll
dt-bindings: imx8mm-clock: Fix the file path
dt-bindings: imx8mq-clock: Fix the file path
clk: qcom: rpmh: Drop unnecessary semicolons
clk: qcom: rpmh: Simplify clk_rpmh_bcm_send_cmd()
clk: tegra: Use NULL for pointer initialization
clk: sprd: add clocks support for SC9863A
clk: sprd: support to get regmap from parent node
clk: sprd: Add macros for referencing parents without strings
clk: sprd: Add dt-bindings include file for SC9863A
dt-bindings: clk: sprd: add bindings for sc9863a clock controller
dt-bindings: clk: sprd: rename the common file name sprd.txt to SoC specific
clk: sprd: add gate for pll clocks
MAINTAINERS: dt: update reference for arm-integrator.txt
clk: mmp2: Fix bit masks for LCDC I/O and pixel clocks
clk: mmp2: Add clock for fifth SD HCI on MMP3
dt-bindings: marvell,mmp2: Add clock id for the fifth SD HCI on MMP3
clk: mmp2: Add clocks for the thermal sensors
dt-bindings: marvell,mmp2: Add clock ids for the thermal sensors
clk: mmp2: add the GPU clocks
...
Diffstat (limited to 'drivers/clk')
95 files changed, 8934 insertions, 796 deletions
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 3732241352ce..8b90357f2a93 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -15,7 +15,11 @@ obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o +obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o +obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o +obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o +obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c new file mode 100644 index 000000000000..c44a431b6c97 --- /dev/null +++ b/drivers/clk/at91/at91rm9200.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/at91.h> + +#include "pmc.h" + +struct sck { + char *n; + char *p; + u8 id; +}; + +struct pck { + char *n; + u8 id; +}; + +static const struct clk_master_characteristics rm9200_mck_characteristics = { + .output = { .min = 0, .max = 80000000 }, + .divisors = { 1, 2, 3, 4 }, +}; + +static u8 rm9200_pll_out[] = { 0, 2 }; + +static const struct clk_range rm9200_pll_outputs[] = { + { .min = 80000000, .max = 160000000 }, + { .min = 150000000, .max = 180000000 }, +}; + +static const struct clk_pll_characteristics rm9200_pll_characteristics = { + .input = { .min = 1000000, .max = 32000000 }, + .num_output = ARRAY_SIZE(rm9200_pll_outputs), + .output = rm9200_pll_outputs, + .out = rm9200_pll_out, +}; + +static const struct sck at91rm9200_systemck[] = { + { .n = "udpck", .p = "usbck", .id = 2 }, + { .n = "uhpck", .p = "usbck", .id = 4 }, + { .n = "pck0", .p = "prog0", .id = 8 }, + { .n = "pck1", .p = "prog1", .id = 9 }, + { .n = "pck2", .p = "prog2", .id = 10 }, + { .n = "pck3", .p = "prog3", .id = 11 }, +}; + +static const struct pck at91rm9200_periphck[] = { + { .n = "pioA_clk", .id = 2 }, + { .n = "pioB_clk", .id = 3 }, + { .n = "pioC_clk", .id = 4 }, + { .n = "pioD_clk", .id = 5 }, + { .n = "usart0_clk", .id = 6 }, + { .n = "usart1_clk", .id = 7 }, + { .n = "usart2_clk", .id = 8 }, + { .n = "usart3_clk", .id = 9 }, + { .n = "mci0_clk", .id = 10 }, + { .n = "udc_clk", .id = 11 }, + { .n = "twi0_clk", .id = 12 }, + { .n = "spi0_clk", .id = 13 }, + { .n = "ssc0_clk", .id = 14 }, + { .n = "ssc1_clk", .id = 15 }, + { .n = "ssc2_clk", .id = 16 }, + { .n = "tc0_clk", .id = 17 }, + { .n = "tc1_clk", .id = 18 }, + { .n = "tc2_clk", .id = 19 }, + { .n = "tc3_clk", .id = 20 }, + { .n = "tc4_clk", .id = 21 }, + { .n = "tc5_clk", .id = 22 }, + { .n = "ohci_clk", .id = 23 }, + { .n = "macb0_clk", .id = 24 }, +}; + +static void __init at91rm9200_pmc_setup(struct device_node *np) +{ + const char *slowxtal_name, *mainxtal_name; + struct pmc_data *at91rm9200_pmc; + u32 usb_div[] = { 1, 2, 0, 0 }; + const char *parent_names[6]; + struct regmap *regmap; + struct clk_hw *hw; + int i; + bool bypass; + + i = of_property_match_string(np, "clock-names", "slow_xtal"); + if (i < 0) + return; + + slowxtal_name = of_clk_get_parent_name(np, i); + + i = of_property_match_string(np, "clock-names", "main_xtal"); + if (i < 0) + return; + mainxtal_name = of_clk_get_parent_name(np, i); + + regmap = device_node_to_regmap(np); + if (IS_ERR(regmap)) + return; + + at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1, + nck(at91rm9200_systemck), + nck(at91rm9200_periphck), 0); + if (!at91rm9200_pmc) + return; + + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, + bypass); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc"); + if (IS_ERR(hw)) + goto err_free; + + at91rm9200_pmc->chws[PMC_MAIN] = hw; + + hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0, + &at91rm9200_pll_layout, + &rm9200_pll_characteristics); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1, + &at91rm9200_pll_layout, + &rm9200_pll_characteristics); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = slowxtal_name; + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + parent_names[3] = "pllbck"; + hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, + &at91rm9200_master_layout, + &rm9200_mck_characteristics); + if (IS_ERR(hw)) + goto err_free; + + at91rm9200_pmc->chws[PMC_MCK] = hw; + + hw = at91rm9200_clk_register_usb(regmap, "usbck", "pllbck", usb_div); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = slowxtal_name; + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + parent_names[3] = "pllbck"; + for (i = 0; i < 4; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, + parent_names, 4, i, + &at91rm9200_programmable_layout); + if (IS_ERR(hw)) + goto err_free; + } + + for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) { + hw = at91_clk_register_system(regmap, at91rm9200_systemck[i].n, + at91rm9200_systemck[i].p, + at91rm9200_systemck[i].id); + if (IS_ERR(hw)) + goto err_free; + + at91rm9200_pmc->shws[at91rm9200_systemck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(at91rm9200_periphck); i++) { + hw = at91_clk_register_peripheral(regmap, + at91rm9200_periphck[i].n, + "masterck", + at91rm9200_periphck[i].id); + if (IS_ERR(hw)) + goto err_free; + + at91rm9200_pmc->phws[at91rm9200_periphck[i].id] = hw; + } + + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91rm9200_pmc); + + return; + +err_free: + pmc_data_free(at91rm9200_pmc); +} +/* + * While the TCB can be used as the clocksource, the system timer is most likely + * to be used instead. However, the pinctrl driver doesn't support probe + * deferring properly. Once this is fixed, this can be switched to a platform + * driver. + */ +CLK_OF_DECLARE_DRIVER(at91rm9200_pmc, "atmel,at91rm9200-pmc", + at91rm9200_pmc_setup); diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c new file mode 100644 index 000000000000..38a7d2d2df0c --- /dev/null +++ b/drivers/clk/at91/at91sam9g45.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/at91.h> + +#include "pmc.h" + +static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 133333333 }, + .divisors = { 1, 2, 4, 3 }, +}; + +static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 }; + +static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; + +static const struct clk_range plla_outputs[] = { + { .min = 745000000, .max = 800000000 }, + { .min = 695000000, .max = 750000000 }, + { .min = 645000000, .max = 700000000 }, + { .min = 595000000, .max = 650000000 }, + { .min = 545000000, .max = 600000000 }, + { .min = 495000000, .max = 555000000 }, + { .min = 445000000, .max = 500000000 }, + { .min = 400000000, .max = 450000000 }, +}; + +static const struct clk_pll_characteristics plla_characteristics = { + .input = { .min = 2000000, .max = 32000000 }, + .num_output = ARRAY_SIZE(plla_outputs), + .output = plla_outputs, + .icpll = plla_icpll, + .out = plla_out, +}; + +static const struct { + char *n; + char *p; + u8 id; +} at91sam9g45_systemck[] = { + { .n = "ddrck", .p = "masterck", .id = 2 }, + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "pck0", .p = "prog0", .id = 8 }, + { .n = "pck1", .p = "prog1", .id = 9 }, +}; + +static const struct clk_pcr_layout at91sam9g45_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .pid_mask = GENMASK(5, 0), + .div_mask = GENMASK(17, 16), +}; + +struct pck { + char *n; + u8 id; +}; + +static const struct pck at91sam9g45_periphck[] = { + { .n = "pioA_clk", .id = 2, }, + { .n = "pioB_clk", .id = 3, }, + { .n = "pioC_clk", .id = 4, }, + { .n = "pioDE_clk", .id = 5, }, + { .n = "trng_clk", .id = 6, }, + { .n = "usart0_clk", .id = 7, }, + { .n = "usart1_clk", .id = 8, }, + { .n = "usart2_clk", .id = 9, }, + { .n = "usart3_clk", .id = 10, }, + { .n = "mci0_clk", .id = 11, }, + { .n = "twi0_clk", .id = 12, }, + { .n = "twi1_clk", .id = 13, }, + { .n = "spi0_clk", .id = 14, }, + { .n = "spi1_clk", .id = 15, }, + { .n = "ssc0_clk", .id = 16, }, + { .n = "ssc1_clk", .id = 17, }, + { .n = "tcb0_clk", .id = 18, }, + { .n = "pwm_clk", .id = 19, }, + { .n = "adc_clk", .id = 20, }, + { .n = "dma0_clk", .id = 21, }, + { .n = "uhphs_clk", .id = 22, }, + { .n = "lcd_clk", .id = 23, }, + { .n = "ac97_clk", .id = 24, }, + { .n = "macb0_clk", .id = 25, }, + { .n = "isi_clk", .id = 26, }, + { .n = "udphs_clk", .id = 27, }, + { .n = "aestdessha_clk", .id = 28, }, + { .n = "mci1_clk", .id = 29, }, + { .n = "vdec_clk", .id = 30, }, +}; + +static void __init at91sam9g45_pmc_setup(struct device_node *np) +{ + const char *slck_name, *mainxtal_name; + struct pmc_data *at91sam9g45_pmc; + const char *parent_names[6]; + struct regmap *regmap; + struct clk_hw *hw; + int i; + bool bypass; + + i = of_property_match_string(np, "clock-names", "slow_clk"); + if (i < 0) + return; + + slck_name = of_clk_get_parent_name(np, i); + + i = of_property_match_string(np, "clock-names", "main_xtal"); + if (i < 0) + return; + mainxtal_name = of_clk_get_parent_name(np, i); + + regmap = syscon_node_to_regmap(np); + if (IS_ERR(regmap)) + return; + + at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1, + nck(at91sam9g45_systemck), + nck(at91sam9g45_periphck), 0); + if (!at91sam9g45_pmc) + return; + + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, + bypass); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc"); + if (IS_ERR(hw)) + goto err_free; + + at91sam9g45_pmc->chws[PMC_MAIN] = hw; + + hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0, + &at91rm9200_pll_layout, &plla_characteristics); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack"); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck"); + if (IS_ERR(hw)) + goto err_free; + + at91sam9g45_pmc->chws[PMC_UTMI] = hw; + + parent_names[0] = slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; + hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, + &at91rm9200_master_layout, + &mck_characteristics); + if (IS_ERR(hw)) + goto err_free; + + at91sam9g45_pmc->chws[PMC_MCK] = hw; + + parent_names[0] = "plladivck"; + parent_names[1] = "utmick"; + hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; + parent_names[4] = "masterck"; + for (i = 0; i < 2; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, + parent_names, 5, i, + &at91sam9g45_programmable_layout); + if (IS_ERR(hw)) + goto err_free; + } + + for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) { + hw = at91_clk_register_system(regmap, at91sam9g45_systemck[i].n, + at91sam9g45_systemck[i].p, + at91sam9g45_systemck[i].id); + if (IS_ERR(hw)) + goto err_free; + + at91sam9g45_pmc->shws[at91sam9g45_systemck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(at91sam9g45_periphck); i++) { + hw = at91_clk_register_peripheral(regmap, + at91sam9g45_periphck[i].n, + "masterck", + at91sam9g45_periphck[i].id); + if (IS_ERR(hw)) + goto err_free; + + at91sam9g45_pmc->phws[at91sam9g45_periphck[i].id] = hw; + } + + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9g45_pmc); + + return; + +err_free: + pmc_data_free(at91sam9g45_pmc); +} +/* + * The TCB is used as the clocksource so its clock is needed early. This means + * this can't be a platform driver. + */ +CLK_OF_DECLARE_DRIVER(at91sam9g45_pmc, "atmel,at91sam9g45-pmc", + at91sam9g45_pmc_setup); diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c new file mode 100644 index 000000000000..8bb39d2ba84b --- /dev/null +++ b/drivers/clk/at91/at91sam9n12.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/at91.h> + +#include "pmc.h" + +static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 133333333 }, + .divisors = { 1, 2, 4, 3 }, + .have_div3_pres = 1, +}; + +static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 }; + +static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; + +static const struct clk_range plla_outputs[] = { + { .min = 745000000, .max = 800000000 }, + { .min = 695000000, .max = 750000000 }, + { .min = 645000000, .max = 700000000 }, + { .min = 595000000, .max = 650000000 }, + { .min = 545000000, .max = 600000000 }, + { .min = 495000000, .max = 555000000 }, + { .min = 445000000, .max = 500000000 }, + { .min = 400000000, .max = 450000000 }, +}; + +static const struct clk_pll_characteristics plla_characteristics = { + .input = { .min = 2000000, .max = 32000000 }, + .num_output = ARRAY_SIZE(plla_outputs), + .output = plla_outputs, + .icpll = plla_icpll, + .out = plla_out, +}; + +static u8 pllb_out[] = { 0 }; + +static const struct clk_range pllb_outputs[] = { + { .min = 30000000, .max = 100000000 }, +}; + +static const struct clk_pll_characteristics pllb_characteristics = { + .input = { .min = 2000000, .max = 32000000 }, + .num_output = ARRAY_SIZE(pllb_outputs), + .output = pllb_outputs, + .out = pllb_out, +}; + +static const struct { + char *n; + char *p; + u8 id; +} at91sam9n12_systemck[] = { + { .n = "ddrck", .p = "masterck", .id = 2 }, + { .n = "lcdck", .p = "masterck", .id = 3 }, + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "udpck", .p = "usbck", .id = 7 }, + { .n = "pck0", .p = "prog0", .id = 8 }, + { .n = "pck1", .p = "prog1", .id = 9 }, +}; + +static const struct clk_pcr_layout at91sam9n12_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .pid_mask = GENMASK(5, 0), + .div_mask = GENMASK(17, 16), +}; + +struct pck { + char *n; + u8 id; +}; + +static const struct pck at91sam9n12_periphck[] = { + { .n = "pioAB_clk", .id = 2, }, + { .n = "pioCD_clk", .id = 3, }, + { .n = "fuse_clk", .id = 4, }, + { .n = "usart0_clk", .id = 5, }, + { .n = "usart1_clk", .id = 6, }, + { .n = "usart2_clk", .id = 7, }, + { .n = "usart3_clk", .id = 8, }, + { .n = "twi0_clk", .id = 9, }, + { .n = "twi1_clk", .id = 10, }, + { .n = "mci0_clk", .id = 12, }, + { .n = "spi0_clk", .id = 13, }, + { .n = "spi1_clk", .id = 14, }, + { .n = "uart0_clk", .id = 15, }, + { .n = "uart1_clk", .id = 16, }, + { .n = "tcb_clk", .id = 17, }, + { .n = "pwm_clk", .id = 18, }, + { .n = "adc_clk", .id = 19, }, + { .n = "dma0_clk", .id = 20, }, + { .n = "uhphs_clk", .id = 22, }, + { .n = "udphs_clk", .id = 23, }, + { .n = "lcdc_clk", .id = 25, }, + { .n = "sha_clk", .id = 27, }, + { .n = "ssc0_clk", .id = 28, }, + { .n = "aes_clk", .id = 29, }, + { .n = "trng_clk", .id = 30, }, +}; + +static void __init at91sam9n12_pmc_setup(struct device_node *np) +{ + struct clk_range range = CLK_RANGE(0, 0); + const char *slck_name, *mainxtal_name; + struct pmc_data *at91sam9n12_pmc; + const char *parent_names[6]; + struct regmap *regmap; + struct clk_hw *hw; + int i; + bool bypass; + + i = of_property_match_string(np, "clock-names", "slow_clk"); + if (i < 0) + return; + + slck_name = of_clk_get_parent_name(np, i); + + i = of_property_match_string(np, "clock-names", "main_xtal"); + if (i < 0) + return; + mainxtal_name = of_clk_get_parent_name(np, i); + + regmap = syscon_node_to_regmap(np); + if (IS_ERR(regmap)) + return; + + at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1, + nck(at91sam9n12_systemck), 31, 0); + if (!at91sam9n12_pmc) + return; + + hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, + 50000000); + if (IS_ERR(hw)) + goto err_free; + + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, + bypass); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = "main_rc_osc"; + parent_names[1] = "main_osc"; + hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2); + if (IS_ERR(hw)) + goto err_free; + + at91sam9n12_pmc->chws[PMC_MAIN] = hw; + + hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0, + &at91rm9200_pll_layout, &plla_characteristics); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack"); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1, + &at91rm9200_pll_layout, &pllb_characteristics); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "pllbck"; + hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, + &at91sam9x5_master_layout, + &mck_characteristics); + if (IS_ERR(hw)) + goto err_free; + + at91sam9n12_pmc->chws[PMC_MCK] = hw; + + hw = at91sam9n12_clk_register_usb(regmap, "usbck", "pllbck"); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "pllbck"; + parent_names[4] = "masterck"; + for (i = 0; i < 2; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, + parent_names, 5, i, + &at91sam9x5_programmable_layout); + if (IS_ERR(hw)) + goto err_free; + } + + for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) { + hw = at91_clk_register_system(regmap, at91sam9n12_systemck[i].n, + at91sam9n12_systemck[i].p, + at91sam9n12_systemck[i].id); + if (IS_ERR(hw)) + goto err_free; + + at91sam9n12_pmc->shws[at91sam9n12_systemck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(at91sam9n12_periphck); i++) { + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &at91sam9n12_pcr_layout, + at91sam9n12_periphck[i].n, + "masterck", + at91sam9n12_periphck[i].id, + &range); + if (IS_ERR(hw)) + goto err_free; + + at91sam9n12_pmc->phws[at91sam9n12_periphck[i].id] = hw; + } + + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9n12_pmc); + + return; + +err_free: + pmc_data_free(at91sam9n12_pmc); +} +/* + * The TCB is used as the clocksource so its clock is needed early. This means + * this can't be a platform driver. + */ +CLK_OF_DECLARE_DRIVER(at91sam9n12_pmc, "atmel,at91sam9n12-pmc", + at91sam9n12_pmc_setup); diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 22aede42a336..31d5c45e30d7 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -25,6 +25,7 @@ struct at91sam9x5_clk_usb { struct clk_hw hw; struct regmap *regmap; u32 usbs_mask; + u8 num_parents; }; #define to_at91sam9x5_clk_usb(hw) \ @@ -75,6 +76,9 @@ static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw, tmp_parent_rate = req->rate * div; tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate); + if (!tmp_parent_rate) + continue; + tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div); if (tmp_rate < req->rate) tmp_diff = req->rate - tmp_rate; @@ -107,7 +111,7 @@ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) { struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - if (index > 1) + if (index >= usb->num_parents) return -EINVAL; regmap_update_bits(usb->regmap, AT91_PMC_USB, usb->usbs_mask, index); @@ -211,7 +215,8 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, usb->hw.init = &init; usb->regmap = regmap; - usb->usbs_mask = SAM9X5_USBS_MASK; + usb->usbs_mask = usbs_mask; + usb->num_parents = num_parents; hw = &usb->hw; ret = clk_hw_register(NULL, &usb->hw); diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index 77398aefeb6d..cc19e8fb83be 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -124,7 +124,6 @@ static const struct { char *n; u8 id; struct clk_range r; - bool pll; } sam9x60_gck[] = { { .n = "flex0_gclk", .id = 5, }, { .n = "flex1_gclk", .id = 6, }, @@ -144,11 +143,9 @@ static const struct { { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, }, { .n = "flex11_gclk", .id = 32, }, { .n = "flex12_gclk", .id = 33, }, - { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, - .pll = true, }, + { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, }, { .n = "pit64b_gclk", .id = 37, }, - { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, - .pll = true, }, + { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, }, { .n = "tcb1_gclk", .id = 45, }, { .n = "dbgu_gclk", .id = 47, }, }; @@ -237,9 +234,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np) parent_names[0] = "pllack"; parent_names[1] = "upllck"; - parent_names[2] = "mainck"; - parent_names[3] = "mainck"; - hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 4); + parent_names[2] = "main_osc"; + hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3); if (IS_ERR(hw)) goto err_free; @@ -290,7 +286,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) sam9x60_gck[i].n, parent_names, 6, sam9x60_gck[i].id, - sam9x60_gck[i].pll, + false, &sam9x60_gck[i].r); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c new file mode 100644 index 000000000000..88506f909c08 --- /dev/null +++ b/drivers/clk/at91/sama5d3.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/at91.h> + +#include "pmc.h" + +static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 166000000 }, + .divisors = { 1, 2, 4, 3 }, +}; + +static u8 plla_out[] = { 0 }; + +static u16 plla_icpll[] = { 0 }; + +static const struct clk_range plla_outputs[] = { + { .min = 400000000, .max = 1000000000 }, +}; + +static const struct clk_pll_characteristics plla_characteristics = { + .input = { .min = 8000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(plla_outputs), + .output = plla_outputs, + .icpll = plla_icpll, + .out = plla_out, +}; + +static const struct clk_pcr_layout sama5d3_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .pid_mask = GENMASK(6, 0), + .div_mask = GENMASK(17, 16), +}; + +static const struct { + char *n; + char *p; + u8 id; +} sama5d3_systemck[] = { + { .n = "ddrck", .p = "masterck", .id = 2 }, + { .n = "lcdck", .p = "masterck", .id = 3 }, + { .n = "smdck", .p = "smdclk", .id = 4 }, + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "udpck", .p = "usbck", .id = 7 }, + { .n = "pck0", .p = "prog0", .id = 8 }, + { .n = "pck1", .p = "prog1", .id = 9 }, + { .n = "pck2", .p = "prog2", .id = 10 }, +}; + +static const struct { + char *n; + u8 id; + struct clk_range r; +} sama5d3_periphck[] = { + { .n = "dbgu_clk", .id = 2, }, + { .n = "hsmc_clk", .id = 5, }, + { .n = "pioA_clk", .id = 6, }, + { .n = "pioB_clk", .id = 7, }, + { .n = "pioC_clk", .id = 8, }, + { .n = "pioD_clk", .id = 9, }, + { .n = "pioE_clk", .id = 10, }, + { .n = "usart0_clk", .id = 12, .r = { .min = 0, .max = 83000000 }, }, + { .n = "usart1_clk", .id = 13, .r = { .min = 0, .max = 83000000 }, }, + { .n = "usart2_clk", .id = 14, .r = { .min = 0, .max = 83000000 }, }, + { .n = "usart3_clk", .id = 15, .r = { .min = 0, .max = 83000000 }, }, + { .n = "uart0_clk", .id = 16, .r = { .min = 0, .max = 83000000 }, }, + { .n = "uart1_clk", .id = 17, .r = { .min = 0, .max = 83000000 }, }, + { .n = "twi0_clk", .id = 18, .r = { .min = 0, .max = 41500000 }, }, + { .n = "twi1_clk", .id = 19, .r = { .min = 0, .max = 41500000 }, }, + { .n = "twi2_clk", .id = 20, .r = { .min = 0, .max = 41500000 }, }, + { .n = "mci0_clk", .id = 21, }, + { .n = "mci1_clk", .id = 22, }, + { .n = "mci2_clk", .id = 23, }, + { .n = "spi0_clk", .id = 24, .r = { .min = 0, .max = 166000000 }, }, + { .n = "spi1_clk", .id = 25, .r = { .min = 0, .max = 166000000 }, }, + { .n = "tcb0_clk", .id = 26, .r = { .min = 0, .max = 166000000 }, }, + { .n = "tcb1_clk", .id = 27, .r = { .min = 0, .max = 166000000 }, }, + { .n = "pwm_clk", .id = 28, }, + { .n = "adc_clk", .id = 29, .r = { .min = 0, .max = 83000000 }, }, + { .n = "dma0_clk", .id = 30, }, + { .n = "dma1_clk", .id = 31, }, + { .n = "uhphs_clk", .id = 32, }, + { .n = "udphs_clk", .id = 33, }, + { .n = "macb0_clk", .id = 34, }, + { .n = "macb1_clk", .id = 35, }, + { .n = "lcdc_clk", .id = 36, }, + { .n = "isi_clk", .id = 37, }, + { .n = "ssc0_clk", .id = 38, .r = { .min = 0, .max = 83000000 }, }, + { .n = "ssc1_clk", .id = 39, .r = { .min = 0, .max = 83000000 }, }, + { .n = "can0_clk", .id = 40, .r = { .min = 0, .max = 83000000 }, }, + { .n = "can1_clk", .id = 41, .r = { .min = 0, .max = 83000000 }, }, + { .n = "sha_clk", .id = 42, }, + { .n = "aes_clk", .id = 43, }, + { .n = "tdes_clk", .id = 44, }, + { .n = "trng_clk", .id = 45, }, + { .n = "fuse_clk", .id = 48, }, + { .n = "mpddr_clk", .id = 49, }, +}; + +static void __init sama5d3_pmc_setup(struct device_node *np) +{ + const char *slck_name, *mainxtal_name; + struct pmc_data *sama5d3_pmc; + const char *parent_names[5]; + struct regmap *regmap; + struct clk_hw *hw; + int i; + bool bypass; + + i = of_property_match_string(np, "clock-names", "slow_clk"); + if (i < 0) + return; + + slck_name = of_clk_get_parent_name(np, i); + + i = of_property_match_string(np, "clock-names", "main_xtal"); + if (i < 0) + return; + mainxtal_name = of_clk_get_parent_name(np, i); + + regmap = syscon_node_to_regmap(np); + if (IS_ERR(regmap)) + return; + + sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1, + nck(sama5d3_systemck), + nck(sama5d3_periphck), 0); + if (!sama5d3_pmc) + return; + + hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, + 50000000); + if (IS_ERR(hw)) + goto err_free; + + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, + bypass); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = "main_rc_osc"; + parent_names[1] = "main_osc"; + hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0, + &sama5d3_pll_layout, &plla_characteristics); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack"); + if (IS_ERR(hw)) + goto err_free; + + hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck"); + if (IS_ERR(hw)) + goto err_free; + + sama5d3_pmc->chws[PMC_UTMI] = hw; + + parent_names[0] = slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; + hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, + &at91sam9x5_master_layout, + &mck_characteristics); + if (IS_ERR(hw)) + goto err_free; + + sama5d3_pmc->chws[PMC_MCK] = hw; + + parent_names[0] = "plladivck"; + parent_names[1] = "utmick"; + hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2); + if (IS_ERR(hw)) + goto err_free; + + hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; + parent_names[4] = "masterck"; + for (i = 0; i < 3; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, + parent_names, 5, i, + &at91sam9x5_programmable_layout); + if (IS_ERR(hw)) + goto err_free; + } + + for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) { + hw = at91_clk_register_system(regmap, sama5d3_systemck[i].n, + sama5d3_systemck[i].p, + sama5d3_systemck[i].id); + if (IS_ERR(hw)) + goto err_free; + + sama5d3_pmc->shws[sama5d3_systemck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(sama5d3_periphck); i++) { + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d3_pcr_layout, + sama5d3_periphck[i].n, + "masterck", + sama5d3_periphck[i].id, + &sama5d3_periphck[i].r); + if (IS_ERR(hw)) + goto err_free; + + sama5d3_pmc->phws[sama5d3_periphck[i].id] = hw; + } + + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama5d3_pmc); + + return; + +err_free: + pmc_data_free(sama5d3_pmc); +} +/* + * The TCB is used as the clocksource so its clock is needed early. This means + * this can't be a platform driver. + */ +CLK_OF_DECLARE_DRIVER(sama5d3_pmc, "atmel,sama5d3-pmc", sama5d3_pmc_setup); diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 6e780c2a9e6b..3c228b018116 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -16,6 +16,8 @@ #include <linux/slab.h> #include <asm/unaligned.h> +#define SI5341_NUM_INPUTS 4 + #define SI5341_MAX_NUM_OUTPUTS 10 #define SI5340_MAX_NUM_OUTPUTS 4 @@ -56,8 +58,8 @@ struct clk_si5341 { struct i2c_client *i2c_client; struct clk_si5341_synth synth[SI5341_NUM_SYNTH]; struct clk_si5341_output clk[SI5341_MAX_NUM_OUTPUTS]; - struct clk *pxtal; - const char *pxtal_name; + struct clk *input_clk[SI5341_NUM_INPUTS]; + const char *input_clk_name[SI5341_NUM_INPUTS]; const u16 *reg_output_offset; const u16 *reg_rdiv_offset; u64 freq_vco; /* 13500–14256 MHz */ @@ -78,10 +80,25 @@ struct clk_si5341_output_config { #define SI5341_DEVICE_REV 0x0005 #define SI5341_STATUS 0x000C #define SI5341_SOFT_RST 0x001C +#define SI5341_IN_SEL 0x0021 +#define SI5341_XAXB_CFG 0x090E +#define SI5341_IN_EN 0x0949 +#define SI5341_INX_TO_PFD_EN 0x094A + +/* Input selection */ +#define SI5341_IN_SEL_MASK 0x06 +#define SI5341_IN_SEL_SHIFT 1 +#define SI5341_IN_SEL_REGCTRL 0x01 +#define SI5341_INX_TO_PFD_SHIFT 4 + +/* XTAL config bits */ +#define SI5341_XAXB_CFG_EXTCLK_EN BIT(0) +#define SI5341_XAXB_CFG_PDNB BIT(1) /* Input dividers (48-bit) */ #define SI5341_IN_PDIV(x) (0x0208 + ((x) * 10)) #define SI5341_IN_PSET(x) (0x020E + ((x) * 10)) +#define SI5341_PX_UPD 0x0230 /* PLL configuration */ #define SI5341_PLL_M_NUM 0x0235 @@ -120,6 +137,10 @@ struct si5341_reg_default { u8 value; }; +static const char * const si5341_input_clock_names[] = { + "in0", "in1", "in2", "xtal" +}; + /* Output configuration registers 0..9 are not quite logically organized */ static const u16 si5341_reg_output_offset[] = { 0x0108, @@ -390,7 +411,112 @@ static unsigned long si5341_clk_recalc_rate(struct clk_hw *hw, return (unsigned long)res; } +static int si5341_clk_get_selected_input(struct clk_si5341 *data) +{ + int err; + u32 val; + + err = regmap_read(data->regmap, SI5341_IN_SEL, &val); + if (err < 0) + return err; + + return (val & SI5341_IN_SEL_MASK) >> SI5341_IN_SEL_SHIFT; +} + +static u8 si5341_clk_get_parent(struct clk_hw *hw) +{ + struct clk_si5341 *data = to_clk_si5341(hw); + int res = si5341_clk_get_selected_input(data); + + if (res < 0) + return 0; /* Apparently we cannot report errors */ + + return res; +} + +static int si5341_clk_reparent(struct clk_si5341 *data, u8 index) +{ + int err; + u8 val; + + val = (index << SI5341_IN_SEL_SHIFT) & SI5341_IN_SEL_MASK; + /* Enable register-based input selection */ + val |= SI5341_IN_SEL_REGCTRL; + + err = regmap_update_bits(data->regmap, + SI5341_IN_SEL, SI5341_IN_SEL_REGCTRL | SI5341_IN_SEL_MASK, val); + if (err < 0) + return err; + + if (index < 3) { + /* Enable input buffer for selected input */ + err = regmap_update_bits(data->regmap, + SI5341_IN_EN, 0x07, BIT(index)); + if (err < 0) + return err; + + /* Enables the input to phase detector */ + err = regmap_update_bits(data->regmap, SI5341_INX_TO_PFD_EN, + 0x7 << SI5341_INX_TO_PFD_SHIFT, + BIT(index + SI5341_INX_TO_PFD_SHIFT)); + if (err < 0) + return err; + + /* Power down XTAL oscillator and buffer */ + err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG, + SI5341_XAXB_CFG_PDNB, 0); + if (err < 0) + return err; + + /* + * Set the P divider to "1". There's no explanation in the + * datasheet of these registers, but the clockbuilder software + * programs a "1" when the input is being used. + */ + err = regmap_write(data->regmap, SI5341_IN_PDIV(index), 1); + if (err < 0) + return err; + + err = regmap_write(data->regmap, SI5341_IN_PSET(index), 1); + if (err < 0) + return err; + + /* Set update PDIV bit */ + err = regmap_write(data->regmap, SI5341_PX_UPD, BIT(index)); + if (err < 0) + return err; + } else { + /* Disable all input buffers */ + err = regmap_update_bits(data->regmap, SI5341_IN_EN, 0x07, 0); + if (err < 0) + return err; + + /* Disable input to phase detector */ + err = regmap_update_bits(data->regmap, SI5341_INX_TO_PFD_EN, + 0x7 << SI5341_INX_TO_PFD_SHIFT, 0); + if (err < 0) + return err; + + /* Power up XTAL oscillator and buffer */ + err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG, + SI5341_XAXB_CFG_PDNB, SI5341_XAXB_CFG_PDNB); + if (err < 0) + return err; + } + + return 0; +} + +static int si5341_clk_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_si5341 *data = to_clk_si5341(hw); + + return si5341_clk_reparent(data, index); +} + static const struct clk_ops si5341_clk_ops = { + .set_parent = si5341_clk_set_parent, + .get_parent = si5341_clk_get_parent, .recalc_rate = si5341_clk_recalc_rate, }; @@ -985,7 +1111,8 @@ static const struct regmap_range si5341_regmap_volatile_range[] = { regmap_reg_range(0x000C, 0x0012), /* Status */ regmap_reg_range(0x001C, 0x001E), /* reset, finc/fdec */ regmap_reg_range(0x00E2, 0x00FE), /* NVM, interrupts, device ready */ - /* Update bits for synth config */ + /* Update bits for P divider and synth config */ + regmap_reg_range(SI5341_PX_UPD, SI5341_PX_UPD), regmap_reg_range(SI5341_SYNTH_N_UPD(0), SI5341_SYNTH_N_UPD(0)), regmap_reg_range(SI5341_SYNTH_N_UPD(1), SI5341_SYNTH_N_UPD(1)), regmap_reg_range(SI5341_SYNTH_N_UPD(2), SI5341_SYNTH_N_UPD(2)), @@ -1122,6 +1249,7 @@ static int si5341_initialize_pll(struct clk_si5341 *data) struct device_node *np = data->i2c_client->dev.of_node; u32 m_num = 0; u32 m_den = 0; + int sel; if (of_property_read_u32(np, "silabs,pll-m-num", &m_num)) { dev_err(&data->i2c_client->dev, @@ -1135,7 +1263,11 @@ static int si5341_initialize_pll(struct clk_si5341 *data) if (!m_num || !m_den) { dev_err(&data->i2c_client->dev, "PLL configuration invalid, assume 14GHz\n"); - m_den = clk_get_rate(data->pxtal) / 10; + sel = si5341_clk_get_selected_input(data); + if (sel < 0) + return sel; + + m_den = clk_get_rate(data->input_clk[sel]) / 10; m_num = 1400000000; } @@ -1143,11 +1275,52 @@ static int si5341_initialize_pll(struct clk_si5341 *data) SI5341_PLL_M_NUM, m_num, m_den); } +static int si5341_clk_select_active_input(struct clk_si5341 *data) +{ + int res; + int err; + int i; + + res = si5341_clk_get_selected_input(data); + if (res < 0) + return res; + + /* If the current register setting is invalid, pick the first input */ + if (!data->input_clk[res]) { + dev_dbg(&data->i2c_client->dev, + "Input %d not connected, rerouting\n", res); + res = -ENODEV; + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { + if (data->input_clk[i]) { + res = i; + break; + } + } + if (res < 0) { + dev_err(&data->i2c_client->dev, + "No clock input available\n"); + return res; + } + } + + /* Make sure the selected clock is also enabled and routed */ + err = si5341_clk_reparent(data, res); + if (err < 0) + return err; + + err = clk_prepare_enable(data->input_clk[res]); + if (err < 0) + return err; + + return res; +} + static int si5341_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct clk_si5341 *data; struct clk_init_data init; + struct clk *input; const char *root_clock_name; const char *synth_clock_names[SI5341_NUM_SYNTH]; int err; @@ -1161,12 +1334,16 @@ static int si5341_probe(struct i2c_client *client, data->i2c_client = client; - data->pxtal = devm_clk_get(&client->dev, "xtal"); - if (IS_ERR(data->pxtal)) { - if (PTR_ERR(data->pxtal) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "Missing xtal clock input\n"); + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { + input = devm_clk_get(&client->dev, si5341_input_clock_names[i]); + if (IS_ERR(input)) { + if (PTR_ERR(input) == -EPROBE_DEFER) + return -EPROBE_DEFER; + data->input_clk_name[i] = si5341_input_clock_names[i]; + } else { + data->input_clk[i] = input; + data->input_clk_name[i] = __clk_get_name(input); + } } err = si5341_dt_parse_dt(client, config); @@ -1188,9 +1365,6 @@ static int si5341_probe(struct i2c_client *client, if (err < 0) return err; - /* "Activate" the xtal (usually a fixed clock) */ - clk_prepare_enable(data->pxtal); - if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) { initialization_required = true; } else { @@ -1223,7 +1397,14 @@ static int si5341_probe(struct i2c_client *client, ARRAY_SIZE(si5341_reg_defaults)); if (err < 0) return err; + } + + /* Input must be up and running at this point */ + err = si5341_clk_select_active_input(data); + if (err < 0) + return err; + if (initialization_required) { /* PLL configuration is required */ err = si5341_initialize_pll(data); if (err < 0) @@ -1231,9 +1412,8 @@ static int si5341_probe(struct i2c_client *client, } /* Register the PLL */ - data->pxtal_name = __clk_get_name(data->pxtal); - init.parent_names = &data->pxtal_name; - init.num_parents = 1; /* For now, only XTAL input supported */ + init.parent_names = data->input_clk_name; + init.num_parents = SI5341_NUM_INPUTS; init.ops = &si5341_clk_ops; init.flags = 0; data->hw.init = &init; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 95adf6c6db3d..39c59f063aa0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -488,7 +488,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_get_rate); -static unsigned long __clk_get_accuracy(struct clk_core *core) +static unsigned long clk_core_get_accuracy_no_lock(struct clk_core *core) { if (!core) return 0; @@ -774,7 +774,7 @@ static void clk_core_rate_restore_protect(struct clk_core *core, int count) * clk_rate_exclusive_get - get exclusivity over the clk rate control * @clk: the clk over which the exclusity of rate control is requested * - * clk_rate_exlusive_get() begins a critical section during which a clock + * clk_rate_exclusive_get() begins a critical section during which a clock * consumer cannot tolerate any other consumer making any operation on the * clock which could result in a rate change or rate glitch. Exclusive clocks * cannot have their rate changed, either directly or indirectly due to changes @@ -1517,18 +1517,12 @@ static void __clk_recalc_accuracies(struct clk_core *core) __clk_recalc_accuracies(child); } -static long clk_core_get_accuracy(struct clk_core *core) +static long clk_core_get_accuracy_recalc(struct clk_core *core) { - unsigned long accuracy; - - clk_prepare_lock(); if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE)) __clk_recalc_accuracies(core); - accuracy = __clk_get_accuracy(core); - clk_prepare_unlock(); - - return accuracy; + return clk_core_get_accuracy_no_lock(core); } /** @@ -1542,10 +1536,16 @@ static long clk_core_get_accuracy(struct clk_core *core) */ long clk_get_accuracy(struct clk *clk) { + long accuracy; + if (!clk) return 0; - return clk_core_get_accuracy(clk->core); + clk_prepare_lock(); + accuracy = clk_core_get_accuracy_recalc(clk->core); + clk_prepare_unlock(); + + return accuracy; } EXPORT_SYMBOL_GPL(clk_get_accuracy); @@ -1599,19 +1599,12 @@ static void __clk_recalc_rates(struct clk_core *core, unsigned long msg) __clk_recalc_rates(child, msg); } -static unsigned long clk_core_get_rate(struct clk_core *core) +static unsigned long clk_core_get_rate_recalc(struct clk_core *core) { - unsigned long rate; - - clk_prepare_lock(); - if (core && (core->flags & CLK_GET_RATE_NOCACHE)) __clk_recalc_rates(core, 0); - rate = clk_core_get_rate_nolock(core); - clk_prepare_unlock(); - - return rate; + return clk_core_get_rate_nolock(core); } /** @@ -1624,10 +1617,16 @@ static unsigned long clk_core_get_rate(struct clk_core *core) */ unsigned long clk_get_rate(struct clk *clk) { + unsigned long rate; + if (!clk) return 0; - return clk_core_get_rate(clk->core); + clk_prepare_lock(); + rate = clk_core_get_rate_recalc(clk->core); + clk_prepare_unlock(); + + return rate; } EXPORT_SYMBOL_GPL(clk_get_rate); @@ -2660,12 +2659,14 @@ static int clk_core_get_phase(struct clk_core *core) { int ret; - clk_prepare_lock(); + lockdep_assert_held(&prepare_lock); + if (!core->ops->get_phase) + return 0; + /* Always try to update cached phase if possible */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - ret = core->phase; - clk_prepare_unlock(); + ret = core->ops->get_phase(core->hw); + if (ret >= 0) + core->phase = ret; return ret; } @@ -2679,10 +2680,16 @@ static int clk_core_get_phase(struct clk_core *core) */ int clk_get_phase(struct clk *clk) { + int ret; + if (!clk) return 0; - return clk_core_get_phase(clk->core); + clk_prepare_lock(); + ret = clk_core_get_phase(clk->core); + clk_prepare_unlock(); + + return ret; } EXPORT_SYMBOL_GPL(clk_get_phase); @@ -2896,13 +2903,22 @@ static struct hlist_head *orphan_list[] = { static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, int level) { - seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n", + int phase; + + seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ", level * 3 + 1, "", 30 - level * 3, c->name, c->enable_count, c->prepare_count, c->protect_count, - clk_core_get_rate(c), clk_core_get_accuracy(c), - clk_core_get_phase(c), - clk_core_get_scaled_duty_cycle(c, 100000)); + clk_core_get_rate_recalc(c), + clk_core_get_accuracy_recalc(c)); + + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "%5d", phase); + else + seq_puts(s, "-----"); + + seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000)); } static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, @@ -2939,6 +2955,7 @@ DEFINE_SHOW_ATTRIBUTE(clk_summary); static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) { + int phase; unsigned long min_rate, max_rate; clk_core_get_boundaries(c, &min_rate, &max_rate); @@ -2948,11 +2965,13 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) seq_printf(s, "\"enable_count\": %d,", c->enable_count); seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); seq_printf(s, "\"protect_count\": %d,", c->protect_count); - seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c)); + seq_printf(s, "\"rate\": %lu,", clk_core_get_rate_recalc(c)); seq_printf(s, "\"min_rate\": %lu,", min_rate); seq_printf(s, "\"max_rate\": %lu,", max_rate); - seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c)); - seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c)); + seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy_recalc(c)); + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "\"phase\": %d,", phase); seq_printf(s, "\"duty_cycle\": %u", clk_core_get_scaled_duty_cycle(c, 100000)); } @@ -3323,7 +3342,9 @@ static void clk_core_reparent_orphans_nolock(void) static int __clk_core_init(struct clk_core *core) { int ret; + struct clk_core *parent; unsigned long rate; + int phase; if (!core) return -EINVAL; @@ -3394,7 +3415,7 @@ static int __clk_core_init(struct clk_core *core) goto out; } - core->parent = __clk_init_parent(core); + parent = core->parent = __clk_init_parent(core); /* * Populate core->parent if parent has already been clk_core_init'd. If @@ -3406,10 +3427,9 @@ static int __clk_core_init(struct clk_core *core) * clocks and re-parent any that are children of the clock currently * being clk_init'd. */ - if (core->parent) { - hlist_add_head(&core->child_node, - &core->parent->children); - core->orphan = core->parent->orphan; + if (parent) { + hlist_add_head(&core->child_node, &parent->children); + core->orphan = parent->orphan; } else if (!core->num_parents) { hlist_add_head(&core->child_node, &clk_root_list); core->orphan = false; @@ -3427,21 +3447,24 @@ static int __clk_core_init(struct clk_core *core) */ if (core->ops->recalc_accuracy) core->accuracy = core->ops->recalc_accuracy(core->hw, - __clk_get_accuracy(core->parent)); - else if (core->parent) - core->accuracy = core->parent->accuracy; + clk_core_get_accuracy_no_lock(parent)); + else if (parent) + core->accuracy = parent->accuracy; else core->accuracy = 0; /* - * Set clk's phase. + * Set clk's phase by clk_core_get_phase() caching the phase. * Since a phase is by definition relative to its parent, just * query the current clock phase, or just assume it's in phase. */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - else - core->phase = 0; + phase = clk_core_get_phase(core); + if (phase < 0) { + ret = phase; + pr_warn("%s: Failed to get phase for clk '%s'\n", __func__, + core->name); + goto out; + } /* * Set clk's duty cycle. @@ -3456,9 +3479,9 @@ static int __clk_core_init(struct clk_core *core) */ if (core->ops->recalc_rate) rate = core->ops->recalc_rate(core->hw, - clk_core_get_rate_nolock(core->parent)); - else if (core->parent) - rate = core->parent->rate; + clk_core_get_rate_nolock(parent)); + else if (parent) + rate = parent->rate; else rate = 0; core->rate = core->req_rate = rate; @@ -4865,8 +4888,8 @@ static int parent_ready(struct device_node *np) * * Return: error code or zero on success */ -int of_clk_detect_critical(struct device_node *np, - int index, unsigned long *flags) +int of_clk_detect_critical(struct device_node *np, int index, + unsigned long *flags) { struct property *prop; const __be32 *cur; diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 20f7c91c03d2..99773519b5a5 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -15,6 +15,7 @@ #define PCG_PREDIV_MAX 8 #define PCG_DIV_SHIFT 0 +#define PCG_CORE_DIV_WIDTH 3 #define PCG_DIV_WIDTH 6 #define PCG_DIV_MAX 64 @@ -91,7 +92,7 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_divider *divider = to_clk_divider(hw); - unsigned long flags = 0; + unsigned long flags; int prediv_value; int div_value; int ret; @@ -126,6 +127,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = { struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, + u32 composite_flags, unsigned long flags) { struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw; @@ -133,6 +135,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, struct clk_divider *div = NULL; struct clk_gate *gate = NULL; struct clk_mux *mux = NULL; + const struct clk_ops *divider_ops; mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) @@ -150,8 +153,16 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, div_hw = &div->hw; div->reg = reg; - div->shift = PCG_PREDIV_SHIFT; - div->width = PCG_PREDIV_WIDTH; + if (composite_flags & IMX_COMPOSITE_CORE) { + div->shift = PCG_DIV_SHIFT; + div->width = PCG_CORE_DIV_WIDTH; + divider_ops = &clk_divider_ops; + } else { + div->shift = PCG_PREDIV_SHIFT; + div->width = PCG_PREDIV_WIDTH; + divider_ops = &imx8m_clk_composite_divider_ops; + } + div->lock = &imx_ccm_lock; div->flags = CLK_DIVIDER_ROUND_CLOSEST; @@ -166,8 +177,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, mux_hw, &clk_mux_ops, div_hw, - &imx8m_clk_composite_divider_ops, - gate_hw, &clk_gate_ops, flags); + divider_ops, gate_hw, &clk_gate_ops, flags); if (IS_ERR(hw)) goto fail; diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index 4b17b91504ed..100ca828b052 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -55,7 +55,7 @@ static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); struct clk_divider *div = to_clk_divider(hw); unsigned int divider, value; - unsigned long flags = 0; + unsigned long flags; u32 val; divider = parent_rate / rate; diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index b569d919c645..58a67630bb6a 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -42,7 +42,7 @@ static int clk_fixup_mux_set_parent(struct clk_hw *hw, u8 index) { struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw); struct clk_mux *mux = to_clk_mux(hw); - unsigned long flags = 0; + unsigned long flags; u32 val; spin_lock_irqsave(mux->lock, flags); diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 7d44ce814806..ce0060e8873e 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -40,7 +40,7 @@ static int clk_gate2_enable(struct clk_hw *hw) { struct clk_gate2 *gate = to_clk_gate2(hw); u32 reg; - unsigned long flags = 0; + unsigned long flags; spin_lock_irqsave(gate->lock, flags); @@ -62,7 +62,7 @@ static void clk_gate2_disable(struct clk_hw *hw) { struct clk_gate2 *gate = to_clk_gate2(hw); u32 reg; - unsigned long flags = 0; + unsigned long flags; spin_lock_irqsave(gate->lock, flags); @@ -101,7 +101,7 @@ static int clk_gate2_is_enabled(struct clk_hw *hw) static void clk_gate2_disable_unused(struct clk_hw *hw) { struct clk_gate2 *gate = to_clk_gate2(hw); - unsigned long flags = 0; + unsigned long flags; u32 reg; spin_lock_irqsave(gate->lock, flags); @@ -154,7 +154,7 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, gate->hw.init = &init; hw = &gate->hw; - ret = clk_hw_register(NULL, hw); + ret = clk_hw_register(dev, hw); if (ret) { kfree(gate); return ERR_PTR(ret); diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index 4bd44d89eaaa..0f647d148abf 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c @@ -208,6 +208,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); base = of_iomap(np, 0); WARN_ON(!base); + of_node_put(np); anatop_base = base; hws[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_hw_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 0c9f7adb41ae..b2057bd42e25 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -802,6 +802,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_hw_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); hws[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_hw_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); hws[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_hw_gate4("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0); + hws[IMX7D_PXP_CLK] = imx_clk_hw_gate4("pxp_clk", "main_axi_root_clk", base + 0x44c0, 0); hws[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_hw_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); hws[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_hw_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); hws[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_hw_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index 0620d6c8c072..3710aa0dee9b 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -8,7 +8,7 @@ */ #include <dt-bindings/clock/imx7ulp-clock.h> -#include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 2ed93fc25087..925670438f23 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -4,12 +4,10 @@ */ #include <dt-bindings/clock/imx8mm-clock.h> -#include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/err.h> -#include <linux/init.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -41,6 +39,8 @@ static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; +static const char * const imx8mm_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m", "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; @@ -283,8 +283,10 @@ static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_8 static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; -static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_out", - "vpu_pll", "sys_pll1_80m", }; +static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", "sys_pll1_200m", + "audio_pll2_out", "sys_pll2_500m", "vpu_pll", "sys_pll1_80m", }; +static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", "sys_pll2_166m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", }; static struct clk_hw_onecell_data *clk_hw_data; static struct clk_hw **hws; @@ -322,6 +324,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop"); base = of_iomap(np, 0); + of_node_put(np); if (WARN_ON(!base)) return -ENOMEM; @@ -414,20 +417,30 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) /* Core Slice */ hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels)); - hws[IMX8MM_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels)); - hws[IMX8MM_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels)); - hws[IMX8MM_CLK_GPU3D_SRC] = imx_clk_hw_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels)); - hws[IMX8MM_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels)); hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); - hws[IMX8MM_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); - hws[IMX8MM_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); - hws[IMX8MM_CLK_GPU3D_CG] = imx_clk_hw_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28); - hws[IMX8MM_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28); hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); - hws[IMX8MM_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); - hws[IMX8MM_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); - hws[IMX8MM_CLK_GPU3D_DIV] = imx_clk_hw_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3); - hws[IMX8MM_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3); + + hws[IMX8MM_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mm_m4_sels, base + 0x8080); + hws[IMX8MM_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mm_vpu_sels, base + 0x8100); + hws[IMX8MM_CLK_GPU3D_CORE] = imx8m_clk_hw_composite_core("gpu3d_core", imx8mm_gpu3d_sels, base + 0x8180); + hws[IMX8MM_CLK_GPU2D_CORE] = imx8m_clk_hw_composite_core("gpu2d_core", imx8mm_gpu2d_sels, base + 0x8200); + + /* For backwards compatibility */ + hws[IMX8MM_CLK_M4_SRC] = hws[IMX8MM_CLK_M4_CORE]; + hws[IMX8MM_CLK_M4_CG] = hws[IMX8MM_CLK_M4_CORE]; + hws[IMX8MM_CLK_M4_DIV] = hws[IMX8MM_CLK_M4_CORE]; + hws[IMX8MM_CLK_VPU_SRC] = hws[IMX8MM_CLK_VPU_CORE]; + hws[IMX8MM_CLK_VPU_CG] = hws[IMX8MM_CLK_VPU_CORE]; + hws[IMX8MM_CLK_VPU_DIV] = hws[IMX8MM_CLK_VPU_CORE]; + hws[IMX8MM_CLK_GPU3D_SRC] = hws[IMX8MM_CLK_GPU3D_CORE]; + hws[IMX8MM_CLK_GPU3D_CG] = hws[IMX8MM_CLK_GPU3D_CORE]; + hws[IMX8MM_CLK_GPU3D_DIV] = hws[IMX8MM_CLK_GPU3D_CORE]; + hws[IMX8MM_CLK_GPU2D_SRC] = hws[IMX8MM_CLK_GPU2D_CORE]; + hws[IMX8MM_CLK_GPU2D_CG] = hws[IMX8MM_CLK_GPU2D_CORE]; + hws[IMX8MM_CLK_GPU2D_DIV] = hws[IMX8MM_CLK_GPU2D_CORE]; + + /* CORE SEL */ + hws[IMX8MM_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", base + 0x9880, 24, 1, imx8mm_a53_core_sels, ARRAY_SIZE(imx8mm_a53_core_sels)); /* BUS */ hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800); @@ -504,6 +517,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mm_wdog_sels, base + 0xb900); hws[IMX8MM_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980); hws[IMX8MM_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mm_clko1_sels, base + 0xba00); + hws[IMX8MM_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mm_clko2_sels, base + 0xba80); hws[IMX8MM_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00); hws[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80); hws[IMX8MM_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00); @@ -564,7 +578,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); hws[IMX8MM_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); hws[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); - hws[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0); + hws[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", base + 0x44f0, 0); hws[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); hws[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); hws[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); @@ -586,7 +600,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); hws[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); hws[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); - hws[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0); + hws[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", base + 0x4660, 0); hws[IMX8MM_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0); hws[IMX8MM_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8); @@ -594,11 +608,14 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); hws[IMX8MM_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL); - hws[IMX8MM_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", - hws[IMX8MM_CLK_A53_DIV]->clk, - hws[IMX8MM_CLK_A53_SRC]->clk, + hws[IMX8MM_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", + hws[IMX8MM_CLK_A53_CORE]->clk, + hws[IMX8MM_CLK_A53_CORE]->clk, hws[IMX8MM_ARM_PLL_OUT]->clk, - hws[IMX8MM_SYS_PLL1_800M]->clk); + hws[IMX8MM_CLK_A53_DIV]->clk); + + clk_hw_set_parent(hws[IMX8MM_CLK_A53_SRC], hws[IMX8MM_SYS_PLL1_800M]); + clk_hw_set_parent(hws[IMX8MM_CLK_A53_CORE], hws[IMX8MM_ARM_PLL_OUT]); imx_check_clk_hws(hws, IMX8MM_CLK_END); diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index a181eb2df876..0bc7070235bd 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -4,12 +4,10 @@ */ #include <dt-bindings/clock/imx8mn-clock.h> -#include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/err.h> -#include <linux/init.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -40,6 +38,8 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; +static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; @@ -317,6 +317,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); base = of_iomap(np, 0); + of_node_put(np); if (WARN_ON(!base)) { ret = -ENOMEM; goto unregister_hws; @@ -413,15 +414,21 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) /* CORE */ hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels)); - hws[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels)); - hws[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels, ARRAY_SIZE(imx8mn_gpu_shader_sels)); hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); - hws[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); - hws[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); - hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); - hws[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); - hws[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); + + hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180); + hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200); + + hws[IMX8MN_CLK_GPU_CORE_SRC] = hws[IMX8MN_CLK_GPU_CORE]; + hws[IMX8MN_CLK_GPU_CORE_CG] = hws[IMX8MN_CLK_GPU_CORE]; + hws[IMX8MN_CLK_GPU_CORE_DIV] = hws[IMX8MN_CLK_GPU_CORE]; + hws[IMX8MN_CLK_GPU_SHADER_SRC] = hws[IMX8MN_CLK_GPU_SHADER]; + hws[IMX8MN_CLK_GPU_SHADER_CG] = hws[IMX8MN_CLK_GPU_SHADER]; + hws[IMX8MN_CLK_GPU_SHADER_DIV] = hws[IMX8MN_CLK_GPU_SHADER]; + + /* CORE SEL */ + hws[IMX8MN_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", base + 0x9880, 24, 1, imx8mn_a53_core_sels, ARRAY_SIZE(imx8mn_a53_core_sels)); /* BUS */ hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800); @@ -529,7 +536,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); hws[IMX8MN_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); hws[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); - hws[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_hw_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0); + hws[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_hw_gate4("gpu_core_root_clk", "gpu_core", base + 0x44f0, 0); hws[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); hws[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); hws[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); @@ -552,11 +559,14 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); - hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", - hws[IMX8MN_CLK_A53_DIV]->clk, - hws[IMX8MN_CLK_A53_SRC]->clk, + hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", + hws[IMX8MN_CLK_A53_CORE]->clk, + hws[IMX8MN_CLK_A53_CORE]->clk, hws[IMX8MN_ARM_PLL_OUT]->clk, - hws[IMX8MN_SYS_PLL1_800M]->clk); + hws[IMX8MN_CLK_A53_DIV]->clk); + + clk_hw_set_parent(hws[IMX8MN_CLK_A53_SRC], hws[IMX8MN_SYS_PLL1_800M]); + clk_hw_set_parent(hws[IMX8MN_CLK_A53_CORE], hws[IMX8MN_ARM_PLL_OUT]); imx_check_clk_hws(hws, IMX8MN_CLK_END); diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index cf192907b7dc..41469e2cc3de 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -4,13 +4,13 @@ */ #include <dt-bindings/clock/imx8mp-clock.h> -#include <linux/clkdev.h> #include <linux/clk-provider.h> #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of_address.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <linux/types.h> #include "clk.h" @@ -34,6 +34,8 @@ static const char * const imx8mp_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; +static const char * const imx8mp_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out", "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; @@ -342,7 +344,7 @@ static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_26 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; -static const char * const imx8mp_hdmi_27m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +static const char * const imx8mp_hdmi_24m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; @@ -434,6 +436,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); anatop_base = of_iomap(np, 0); + of_node_put(np); if (WARN_ON(!anatop_base)) return -ENOMEM; @@ -553,6 +556,9 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3); hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3); + /* CORE SEL */ + hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels)); + hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800); hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880); hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900); @@ -631,7 +637,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_IPP_DO_CLKO1] = imx8m_clk_hw_composite("ipp_do_clko1", imx8mp_ipp_do_clko1_sels, ccm_base + 0xba00); hws[IMX8MP_CLK_IPP_DO_CLKO2] = imx8m_clk_hw_composite("ipp_do_clko2", imx8mp_ipp_do_clko2_sels, ccm_base + 0xba80); hws[IMX8MP_CLK_HDMI_FDCC_TST] = imx8m_clk_hw_composite("hdmi_fdcc_tst", imx8mp_hdmi_fdcc_tst_sels, ccm_base + 0xbb00); - hws[IMX8MP_CLK_HDMI_27M] = imx8m_clk_hw_composite("hdmi_27m", imx8mp_hdmi_27m_sels, ccm_base + 0xbb80); + hws[IMX8MP_CLK_HDMI_24M] = imx8m_clk_hw_composite("hdmi_24m", imx8mp_hdmi_24m_sels, ccm_base + 0xbb80); hws[IMX8MP_CLK_HDMI_REF_266M] = imx8m_clk_hw_composite("hdmi_ref_266m", imx8mp_hdmi_ref_266m_sels, ccm_base + 0xbc00); hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80); hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00); @@ -671,6 +677,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0); hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0); hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0); + hws[IMX8MP_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", ccm_base + 0x4220, 0); hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0); hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0); hws[IMX8MP_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", ccm_base + 0x4290, 0); @@ -722,11 +729,14 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0); hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0); - hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", - hws[IMX8MP_CLK_A53_DIV]->clk, - hws[IMX8MP_CLK_A53_SRC]->clk, + hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", + hws[IMX8MP_CLK_A53_CORE]->clk, + hws[IMX8MP_CLK_A53_CORE]->clk, hws[IMX8MP_ARM_PLL_OUT]->clk, - hws[IMX8MP_SYS_PLL1_800M]->clk); + hws[IMX8MP_CLK_A53_DIV]->clk); + + clk_hw_set_parent(hws[IMX8MP_CLK_A53_SRC], hws[IMX8MP_SYS_PLL1_800M]); + clk_hw_set_parent(hws[IMX8MP_CLK_A53_CORE], hws[IMX8MP_ARM_PLL_OUT]); imx_check_clk_hws(hws, IMX8MP_CLK_END); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 4c0edca1a6d0..fdc68db68de5 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -5,7 +5,7 @@ */ #include <dt-bindings/clock/imx8mq-clock.h> -#include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> @@ -41,6 +41,8 @@ static const char * const video2_pll_out_sels[] = {"video2_pll1_ref_sel", }; static const char * const imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll_out", }; +static const char * const imx8mq_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + static const char * const imx8mq_arm_m4_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_250m", "sys1_pll_266m", "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", "sys3_pll_out", }; @@ -305,6 +307,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop"); base = of_iomap(np, 0); + of_node_put(np); if (WARN_ON(!base)) return -ENOMEM; @@ -403,22 +406,29 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) /* CORE */ hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); - hws[IMX8MQ_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels)); - hws[IMX8MQ_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels)); - hws[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels)); - hws[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels)); - hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL); - hws[IMX8MQ_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); - hws[IMX8MQ_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); - hws[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); - hws[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); - hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); - hws[IMX8MQ_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); - hws[IMX8MQ_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); - hws[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); - hws[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); + + hws[IMX8MQ_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mq_arm_m4_sels, base + 0x8080); + hws[IMX8MQ_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mq_vpu_sels, base + 0x8100); + hws[IMX8MQ_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mq_gpu_core_sels, base + 0x8180); + hws[IMX8MQ_CLK_GPU_SHADER] = imx8m_clk_hw_composite("gpu_shader", imx8mq_gpu_shader_sels, base + 0x8200); + /* For backwards compatibility */ + hws[IMX8MQ_CLK_M4_SRC] = hws[IMX8MQ_CLK_M4_CORE]; + hws[IMX8MQ_CLK_M4_CG] = hws[IMX8MQ_CLK_M4_CORE]; + hws[IMX8MQ_CLK_M4_DIV] = hws[IMX8MQ_CLK_M4_CORE]; + hws[IMX8MQ_CLK_VPU_SRC] = hws[IMX8MQ_CLK_VPU_CORE]; + hws[IMX8MQ_CLK_VPU_CG] = hws[IMX8MQ_CLK_VPU_CORE]; + hws[IMX8MQ_CLK_VPU_DIV] = hws[IMX8MQ_CLK_VPU_CORE]; + hws[IMX8MQ_CLK_GPU_CORE_SRC] = hws[IMX8MQ_CLK_GPU_CORE]; + hws[IMX8MQ_CLK_GPU_CORE_CG] = hws[IMX8MQ_CLK_GPU_CORE]; + hws[IMX8MQ_CLK_GPU_CORE_DIV] = hws[IMX8MQ_CLK_GPU_CORE]; + hws[IMX8MQ_CLK_GPU_SHADER_SRC] = hws[IMX8MQ_CLK_GPU_SHADER]; + hws[IMX8MQ_CLK_GPU_SHADER_CG] = hws[IMX8MQ_CLK_GPU_SHADER]; + hws[IMX8MQ_CLK_GPU_SHADER_DIV] = hws[IMX8MQ_CLK_GPU_SHADER]; + + /* CORE SEL */ + hws[IMX8MQ_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", base + 0x9880, 24, 1, imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)); /* BUS */ hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800); @@ -567,7 +577,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) hws[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); hws[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); hws[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_hw_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); - hws[IMX8MQ_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0); + hws[IMX8MQ_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_core", base + 0x4570, 0); hws[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_hw_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); hws[IMX8MQ_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss); hws[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss); @@ -583,11 +593,14 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) hws[IMX8MQ_GPT_3M_CLK] = imx_clk_hw_fixed_factor("gpt_3m", "osc_25m", 1, 8); hws[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); - hws[IMX8MQ_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", - hws[IMX8MQ_CLK_A53_DIV]->clk, - hws[IMX8MQ_CLK_A53_SRC]->clk, + hws[IMX8MQ_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", + hws[IMX8MQ_CLK_A53_CORE]->clk, + hws[IMX8MQ_CLK_A53_CORE]->clk, hws[IMX8MQ_ARM_PLL_OUT]->clk, - hws[IMX8MQ_SYS1_PLL_800M]->clk); + hws[IMX8MQ_CLK_A53_DIV]->clk); + + clk_hw_set_parent(hws[IMX8MQ_CLK_A53_SRC], hws[IMX8MQ_SYS1_PLL_800M]); + clk_hw_set_parent(hws[IMX8MQ_CLK_A53_CORE], hws[IMX8MQ_ARM_PLL_OUT]); imx_check_clk_hws(hws, IMX8MQ_CLK_END); diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c index de93ce73101b..78e1f7641aaa 100644 --- a/drivers/clk/imx/clk-pfdv2.c +++ b/drivers/clk/imx/clk-pfdv2.c @@ -98,26 +98,45 @@ static unsigned long clk_pfdv2_recalc_rate(struct clk_hw *hw, return tmp; } -static long clk_pfdv2_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pfdv2_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - u64 tmp = *prate; + unsigned long parent_rates[] = { + 480000000, + 528000000, + req->best_parent_rate + }; + unsigned long best_rate = -1UL, rate = req->rate; + unsigned long best_parent_rate = req->best_parent_rate; + u64 tmp; u8 frac; + int i; + + for (i = 0; i < ARRAY_SIZE(parent_rates); i++) { + tmp = parent_rates[i]; + tmp = tmp * 18 + rate / 2; + do_div(tmp, rate); + frac = tmp; + + if (frac < 12) + frac = 12; + else if (frac > 35) + frac = 35; + + tmp = parent_rates[i]; + tmp *= 18; + do_div(tmp, frac); + + if (abs(tmp - req->rate) < abs(best_rate - req->rate)) { + best_rate = tmp; + best_parent_rate = parent_rates[i]; + } + } - tmp = tmp * 18 + rate / 2; - do_div(tmp, rate); - frac = tmp; - - if (frac < 12) - frac = 12; - else if (frac > 35) - frac = 35; - - tmp = *prate; - tmp *= 18; - do_div(tmp, frac); + req->best_parent_rate = best_parent_rate; + req->rate = best_rate; - return tmp; + return 0; } static int clk_pfdv2_is_enabled(struct clk_hw *hw) @@ -139,6 +158,12 @@ static int clk_pfdv2_set_rate(struct clk_hw *hw, unsigned long rate, u32 val; u8 frac; + if (!rate) + return -EINVAL; + + /* PFD can NOT change rate without gating */ + WARN_ON(clk_pfdv2_is_enabled(hw)); + tmp = tmp * 18 + rate / 2; do_div(tmp, rate); frac = tmp; @@ -161,7 +186,7 @@ static const struct clk_ops clk_pfdv2_ops = { .enable = clk_pfdv2_enable, .disable = clk_pfdv2_disable, .recalc_rate = clk_pfdv2_recalc_rate, - .round_rate = clk_pfdv2_round_rate, + .determine_rate = clk_pfdv2_determine_rate, .set_rate = clk_pfdv2_set_rate, .is_enabled = clk_pfdv2_is_enabled, }; @@ -189,7 +214,7 @@ struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, init.ops = &clk_pfdv2_ops; init.parent_names = &parent_name; init.num_parents = 1; - init.flags = CLK_SET_RATE_GATE; + init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; pfd->hw.init = &init; diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 5b0519a81a7a..a83bbbee77d9 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -55,8 +55,10 @@ static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { }; static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { + PLL_1443X_RATE(1039500000U, 173, 2, 1, 16384), PLL_1443X_RATE(650000000U, 325, 3, 2, 0), PLL_1443X_RATE(594000000U, 198, 2, 2, 0), + PLL_1443X_RATE(519750000U, 173, 2, 2, 16384), PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), }; @@ -408,6 +410,8 @@ struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, default: pr_err("%s: Unknown pll type for pll clk %s\n", __func__, name); + kfree(pll); + return ERR_PTR(-EINVAL); }; pll->base = base; diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c index f51a800c268c..a49450431855 100644 --- a/drivers/clk/imx/clk-pllv4.c +++ b/drivers/clk/imx/clk-pllv4.c @@ -54,7 +54,7 @@ static inline int clk_pllv4_wait_lock(struct clk_pllv4 *pll) csr, csr & PLL_VLD, 0, LOCK_TIMEOUT_US); } -static int clk_pllv4_is_enabled(struct clk_hw *hw) +static int clk_pllv4_is_prepared(struct clk_hw *hw) { struct clk_pllv4 *pll = to_clk_pllv4(hw); @@ -175,7 +175,7 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int clk_pllv4_enable(struct clk_hw *hw) +static int clk_pllv4_prepare(struct clk_hw *hw) { u32 val; struct clk_pllv4 *pll = to_clk_pllv4(hw); @@ -187,7 +187,7 @@ static int clk_pllv4_enable(struct clk_hw *hw) return clk_pllv4_wait_lock(pll); } -static void clk_pllv4_disable(struct clk_hw *hw) +static void clk_pllv4_unprepare(struct clk_hw *hw) { u32 val; struct clk_pllv4 *pll = to_clk_pllv4(hw); @@ -201,9 +201,9 @@ static const struct clk_ops clk_pllv4_ops = { .recalc_rate = clk_pllv4_recalc_rate, .round_rate = clk_pllv4_round_rate, .set_rate = clk_pllv4_set_rate, - .enable = clk_pllv4_enable, - .disable = clk_pllv4_disable, - .is_enabled = clk_pllv4_is_enabled, + .prepare = clk_pllv4_prepare, + .unprepare = clk_pllv4_unprepare, + .is_prepared = clk_pllv4_is_prepared, }; struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c index acd1b9002be6..d4a2be16d132 100644 --- a/drivers/clk/imx/clk-sscg-pll.c +++ b/drivers/clk/imx/clk-sscg-pll.c @@ -195,10 +195,10 @@ static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup, uint64_t ref) { - int ret = -EINVAL; + int ret; if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ) - return ret; + return -EINVAL; temp_setup->vco1 = ref; @@ -254,10 +254,10 @@ static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup, uint64_t ref) { - int ret = -EINVAL; + int ret; if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ) - return ret; + return -EINVAL; temp_setup->ref = ref; @@ -428,7 +428,7 @@ static int __clk_sscg_pll_determine_rate(struct clk_hw *hw, struct clk_sscg_pll_setup *setup = &pll->setup; struct clk_hw *parent_hw = NULL; int bypass_parent_index; - int ret = -EINVAL; + int ret; req->max_rate = max; req->min_rate = min; @@ -467,10 +467,10 @@ static int clk_sscg_pll_determine_rate(struct clk_hw *hw, uint64_t rate = req->rate; uint64_t min = req->min_rate; uint64_t max = req->max_rate; - int ret = -EINVAL; + int ret; if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ) - return ret; + return -EINVAL; ret = __clk_sscg_pll_determine_rate(hw, req, req->rate, req->rate, rate, PLL_BYPASS2); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index b05213b91dcf..f074dd8ec42e 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -477,20 +477,29 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk *div, struct clk *mux, struct clk *pll, struct clk *step); +#define IMX_COMPOSITE_CORE BIT(0) + struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, + u32 composite_flags, unsigned long flags); +#define imx8m_clk_hw_composite_core(name, parent_names, reg) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, \ + IMX_COMPOSITE_CORE, \ + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + #define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \ flags) \ to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \ - num_parents, reg, flags)) + num_parents, reg, 0, flags)) #define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \ imx8m_clk_hw_composite_flags(name, parent_names, \ - ARRAY_SIZE(parent_names), reg, \ + ARRAY_SIZE(parent_names), reg, 0, \ flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) #define __imx8m_clk_composite(name, parent_names, reg, flags) \ diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index 956dd653a43d..c051ecba5cf8 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -432,8 +432,10 @@ static void __init jz4770_cgu_init(struct device_node *np) cgu = ingenic_cgu_new(jz4770_cgu_clocks, ARRAY_SIZE(jz4770_cgu_clocks), np); - if (!cgu) + if (!cgu) { pr_err("%s: failed to initialise CGU\n", __func__); + return; + } retval = ingenic_cgu_register_clocks(cgu); if (retval) diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index ea905ff72bf0..c758f1643067 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -9,14 +9,16 @@ #include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/of.h> + #include <dt-bindings/clock/jz4780-cgu.h> #include "cgu.h" #include "pm.h" /* CGU register offsets */ #define CGU_REG_CLOCKCONTROL 0x00 -#define CGU_REG_PLLCONTROL 0x0c +#define CGU_REG_LCR 0x04 #define CGU_REG_APLL 0x10 #define CGU_REG_MPLL 0x14 #define CGU_REG_EPLL 0x18 @@ -46,8 +48,8 @@ #define CGU_REG_CLOCKSTATUS 0xd4 /* bits within the OPCR register */ -#define OPCR_SPENDN0 (1 << 7) -#define OPCR_SPENDN1 (1 << 6) +#define OPCR_SPENDN0 BIT(7) +#define OPCR_SPENDN1 BIT(6) /* bits within the USBPCR register */ #define USBPCR_USB_MODE BIT(31) @@ -88,6 +90,13 @@ #define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT) #define USBVBFIL_USBVBFIL_MASK (0xffff) +/* bits within the LCR register */ +#define LCR_PD_SCPU BIT(31) +#define LCR_SCPUS BIT(27) + +/* bits within the CLKGR1 register */ +#define CLKGR1_CORE1 BIT(15) + static struct ingenic_cgu *cgu; static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw) @@ -205,6 +214,42 @@ static const struct clk_ops jz4780_otg_phy_ops = { .set_rate = jz4780_otg_phy_set_rate, }; +static int jz4780_core1_enable(struct clk_hw *hw) +{ + struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); + struct ingenic_cgu *cgu = ingenic_clk->cgu; + const unsigned int timeout = 5000; + unsigned long flags; + int retval; + u32 lcr, clkgr1; + + spin_lock_irqsave(&cgu->lock, flags); + + lcr = readl(cgu->base + CGU_REG_LCR); + lcr &= ~LCR_PD_SCPU; + writel(lcr, cgu->base + CGU_REG_LCR); + + clkgr1 = readl(cgu->base + CGU_REG_CLKGR1); + clkgr1 &= ~CLKGR1_CORE1; + writel(clkgr1, cgu->base + CGU_REG_CLKGR1); + + spin_unlock_irqrestore(&cgu->lock, flags); + + /* wait for the CPU to be powered up */ + retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr, + !(lcr & LCR_SCPUS), 10, timeout); + if (retval == -ETIMEDOUT) { + pr_err("%s: Wait for power up core1 timeout\n", __func__); + return retval; + } + + return 0; +} + +static const struct clk_ops jz4780_core1_ops = { + .enable = jz4780_core1_enable, +}; + static const s8 pll_od_encoding[16] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, @@ -699,9 +744,9 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = { }, [JZ4780_CLK_CORE1] = { - "core1", CGU_CLK_GATE, + "core1", CGU_CLK_CUSTOM, .parents = { JZ4780_CLK_CPU, -1, -1, -1 }, - .gate = { CGU_REG_CLKGR1, 15 }, + .custom = { &jz4780_core1_ops }, }, }; diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index ad7daa494fd4..153a954b0d2f 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -189,7 +189,7 @@ static long ingenic_tcu_round_rate(struct clk_hw *hw, unsigned long req_rate, u8 prescale; if (req_rate > rate) - return -EINVAL; + return rate; prescale = ingenic_tcu_get_prescale(rate, req_rate); @@ -317,10 +317,17 @@ static const struct ingenic_soc_info jz4770_soc_info = { .has_tcu_clk = false, }; +static const struct ingenic_soc_info x1000_soc_info = { + .num_channels = 8, + .has_ost = false, /* X1000 has OST, but it not belong TCU */ + .has_tcu_clk = false, +}; + static const struct of_device_id ingenic_tcu_of_match[] __initconst = { { .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, }, { .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, }, { .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, }, + { .compatible = "ingenic,x1000-tcu", .data = &x1000_soc_info, }, { /* sentinel */ } }; @@ -471,3 +478,4 @@ static void __init ingenic_tcu_init(struct device_node *np) CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init); CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-tcu", ingenic_tcu_init); CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-tcu", ingenic_tcu_init); +CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-tcu", ingenic_tcu_init); diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig index 38aeefb1e808..ab613f28b502 100644 --- a/drivers/clk/keystone/Kconfig +++ b/drivers/clk/keystone/Kconfig @@ -26,3 +26,11 @@ config TI_SCI_CLK_PROBE_FROM_FW This is mostly only useful for debugging purposes, and will increase the boot time of the device. If you want the clocks probed from firmware, say Y. Otherwise, say N. + +config TI_SYSCON_CLK + tristate "Syscon based clock driver for K2/K3 SoCs" + depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST + default ARCH_KEYSTONE || ARCH_K3 + help + This adds clock driver support for syscon based gate + clocks on TI's K2 and K3 SoCs. diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile index d044de6f965c..0e426e648f7c 100644 --- a/drivers/clk/keystone/Makefile +++ b/drivers/clk/keystone/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_COMMON_CLK_KEYSTONE) += pll.o gate.o obj-$(CONFIG_TI_SCI_CLK) += sci-clk.o +obj-$(CONFIG_TI_SYSCON_CLK) += syscon-clk.o diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c new file mode 100644 index 000000000000..8d7dbea3bd30 --- /dev/null +++ b/drivers/clk/keystone/syscon-clk.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ + */ + +#include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +struct ti_syscon_gate_clk_priv { + struct clk_hw hw; + struct regmap *regmap; + u32 reg; + u32 idx; +}; + +struct ti_syscon_gate_clk_data { + char *name; + u32 offset; + u32 bit_idx; +}; + +static struct +ti_syscon_gate_clk_priv *to_ti_syscon_gate_clk_priv(struct clk_hw *hw) +{ + return container_of(hw, struct ti_syscon_gate_clk_priv, hw); +} + +static int ti_syscon_gate_clk_enable(struct clk_hw *hw) +{ + struct ti_syscon_gate_clk_priv *priv = to_ti_syscon_gate_clk_priv(hw); + + return regmap_write_bits(priv->regmap, priv->reg, priv->idx, + priv->idx); +} + +static void ti_syscon_gate_clk_disable(struct clk_hw *hw) +{ + struct ti_syscon_gate_clk_priv *priv = to_ti_syscon_gate_clk_priv(hw); + + regmap_write_bits(priv->regmap, priv->reg, priv->idx, 0); +} + +static int ti_syscon_gate_clk_is_enabled(struct clk_hw *hw) +{ + unsigned int val; + struct ti_syscon_gate_clk_priv *priv = to_ti_syscon_gate_clk_priv(hw); + + regmap_read(priv->regmap, priv->reg, &val); + + return !!(val & priv->idx); +} + +static const struct clk_ops ti_syscon_gate_clk_ops = { + .enable = ti_syscon_gate_clk_enable, + .disable = ti_syscon_gate_clk_disable, + .is_enabled = ti_syscon_gate_clk_is_enabled, +}; + +static struct clk_hw +*ti_syscon_gate_clk_register(struct device *dev, struct regmap *regmap, + const struct ti_syscon_gate_clk_data *data) +{ + struct ti_syscon_gate_clk_priv *priv; + struct clk_init_data init; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return ERR_PTR(-ENOMEM); + + init.name = data->name; + init.ops = &ti_syscon_gate_clk_ops; + init.parent_names = NULL; + init.num_parents = 0; + init.flags = 0; + + priv->regmap = regmap; + priv->reg = data->offset; + priv->idx = BIT(data->bit_idx); + priv->hw.init = &init; + + ret = devm_clk_hw_register(dev, &priv->hw); + if (ret) + return ERR_PTR(ret); + + return &priv->hw; +} + +static int ti_syscon_gate_clk_probe(struct platform_device *pdev) +{ + const struct ti_syscon_gate_clk_data *data, *p; + struct clk_hw_onecell_data *hw_data; + struct device *dev = &pdev->dev; + struct regmap *regmap; + int num_clks, i; + + data = device_get_match_data(dev); + if (!data) + return -EINVAL; + + regmap = syscon_node_to_regmap(dev->of_node); + if (IS_ERR(regmap)) { + if (PTR_ERR(regmap) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_err(dev, "failed to find parent regmap\n"); + return PTR_ERR(regmap); + } + + num_clks = 0; + for (p = data; p->name; p++) + num_clks++; + + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks), + GFP_KERNEL); + if (!hw_data) + return -ENOMEM; + + hw_data->num = num_clks; + + for (i = 0; i < num_clks; i++) { + hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap, + &data[i]); + if (IS_ERR(hw_data->hws[i])) + dev_warn(dev, "failed to register %s\n", + data[i].name); + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + hw_data); +} + +#define TI_SYSCON_CLK_GATE(_name, _offset, _bit_idx) \ + { \ + .name = _name, \ + .offset = (_offset), \ + .bit_idx = (_bit_idx), \ + } + +static const struct ti_syscon_gate_clk_data am654_clk_data[] = { + TI_SYSCON_CLK_GATE("ehrpwm_tbclk0", 0x0, 0), + TI_SYSCON_CLK_GATE("ehrpwm_tbclk1", 0x4, 0), + TI_SYSCON_CLK_GATE("ehrpwm_tbclk2", 0x8, 0), + TI_SYSCON_CLK_GATE("ehrpwm_tbclk3", 0xc, 0), + TI_SYSCON_CLK_GATE("ehrpwm_tbclk4", 0x10, 0), + TI_SYSCON_CLK_GATE("ehrpwm_tbclk5", 0x14, 0), + { /* Sentinel */ }, +}; + +static const struct of_device_id ti_syscon_gate_clk_ids[] = { + { + .compatible = "ti,am654-ehrpwm-tbclk", + .data = &am654_clk_data, + }, + { } +}; +MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids); + +static struct platform_driver ti_syscon_gate_clk_driver = { + .probe = ti_syscon_gate_clk_probe, + .driver = { + .name = "ti-syscon-gate-clk", + .of_match_table = ti_syscon_gate_clk_ids, + }, +}; +module_platform_driver(ti_syscon_gate_clk_driver); + +MODULE_AUTHOR("Vignesh Raghavendra <vigneshr@ti.com>"); +MODULE_DESCRIPTION("Syscon backed gate-clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index d2760a021301..fad616cac01e 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -3862,6 +3862,111 @@ static struct clk_regmap g12a_ts = { }, }; +/* SPICC SCLK source clock */ + +static const struct clk_parent_data spicc_sclk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_clk81.hw }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, + { .hw = &g12a_fclk_div7.hw }, +}; + +static struct clk_regmap g12a_spicc0_sclk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SPICC_CLK_CNTL, + .mask = 7, + .shift = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0_sclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_sclk_parent_data, + .num_parents = ARRAY_SIZE(spicc_sclk_parent_data), + }, +}; + +static struct clk_regmap g12a_spicc0_sclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SPICC_CLK_CNTL, + .shift = 0, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0_sclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc0_sclk_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_spicc0_sclk = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SPICC_CLK_CNTL, + .bit_idx = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0_sclk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc0_sclk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_spicc1_sclk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SPICC_CLK_CNTL, + .mask = 7, + .shift = 23, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc1_sclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_sclk_parent_data, + .num_parents = ARRAY_SIZE(spicc_sclk_parent_data), + }, +}; + +static struct clk_regmap g12a_spicc1_sclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SPICC_CLK_CNTL, + .shift = 16, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc1_sclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc1_sclk_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_spicc1_sclk = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SPICC_CLK_CNTL, + .bit_idx = 22, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc1_sclk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc1_sclk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + #define MESON_GATE(_name, _reg, _bit) \ MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw) @@ -4159,6 +4264,12 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = { [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, [CLKID_TS_DIV] = &g12a_ts_div.hw, [CLKID_TS] = &g12a_ts.hw, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel.hw, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div.hw, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk.hw, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4408,6 +4519,12 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = { [CLKID_CPUB_CLK_AXI] = &g12b_cpub_clk_axi.hw, [CLKID_CPUB_CLK_TRACE_SEL] = &g12b_cpub_clk_trace_sel.hw, [CLKID_CPUB_CLK_TRACE] = &g12b_cpub_clk_trace.hw, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel.hw, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div.hw, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk.hw, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4642,6 +4759,12 @@ static struct clk_hw_onecell_data sm1_hw_onecell_data = { [CLKID_CPU1_CLK] = &sm1_cpu1_clk.hw, [CLKID_CPU2_CLK] = &sm1_cpu2_clk.hw, [CLKID_CPU3_CLK] = &sm1_cpu3_clk.hw, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel.hw, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div.hw, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk.hw, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4877,6 +5000,12 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &sm1_cpu1_clk, &sm1_cpu2_clk, &sm1_cpu3_clk, + &g12a_spicc0_sclk_sel, + &g12a_spicc0_sclk_div, + &g12a_spicc0_sclk, + &g12a_spicc1_sclk_sel, + &g12a_spicc1_sclk_div, + &g12a_spicc1_sclk, }; static const struct reg_sequence g12a_init_regs[] = { diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index 9df4068aced1..a8852556836e 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -255,8 +255,12 @@ #define CLKID_DSU_CLK_DYN1 249 #define CLKID_DSU_CLK_DYN 250 #define CLKID_DSU_CLK_FINAL 251 +#define CLKID_SPICC0_SCLK_SEL 256 +#define CLKID_SPICC0_SCLK_DIV 257 +#define CLKID_SPICC1_SCLK_SEL 259 +#define CLKID_SPICC1_SCLK_DIV 260 -#define NR_CLKS 256 +#define NR_CLKS 262 /* include the CLKIDs that have been made part of the DT binding */ #include <dt-bindings/clock/g12a-clkc.h> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 1f9c056e684c..5fd6a574f8c3 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -2613,19 +2613,12 @@ static MESON_GATE(gxbb_assist_misc, HHI_GCLK_MPEG0, 23); static MESON_GATE(gxbb_emmc_a, HHI_GCLK_MPEG0, 24); static MESON_GATE(gxbb_emmc_b, HHI_GCLK_MPEG0, 25); static MESON_GATE(gxbb_emmc_c, HHI_GCLK_MPEG0, 26); +static MESON_GATE(gxl_acodec, HHI_GCLK_MPEG0, 28); static MESON_GATE(gxbb_spi, HHI_GCLK_MPEG0, 30); static MESON_GATE(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2); static MESON_GATE(gxbb_eth, HHI_GCLK_MPEG1, 3); static MESON_GATE(gxbb_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6); -static MESON_GATE(gxbb_iec958, HHI_GCLK_MPEG1, 7); -static MESON_GATE(gxbb_i2s_out, HHI_GCLK_MPEG1, 8); -static MESON_GATE(gxbb_amclk, HHI_GCLK_MPEG1, 9); -static MESON_GATE(gxbb_aififo2, HHI_GCLK_MPEG1, 10); -static MESON_GATE(gxbb_mixer, HHI_GCLK_MPEG1, 11); -static MESON_GATE(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12); -static MESON_GATE(gxbb_adc, HHI_GCLK_MPEG1, 13); static MESON_GATE(gxbb_blkmv, HHI_GCLK_MPEG1, 14); static MESON_GATE(gxbb_aiu, HHI_GCLK_MPEG1, 15); static MESON_GATE(gxbb_uart1, HHI_GCLK_MPEG1, 16); @@ -2680,6 +2673,16 @@ static MESON_GATE(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2); static MESON_GATE(gxbb_ao_iface, HHI_GCLK_AO, 3); static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4); +/* AIU gates */ +static MESON_PCLK(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6, &gxbb_aiu.hw); +static MESON_PCLK(gxbb_iec958, HHI_GCLK_MPEG1, 7, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_i2s_out, HHI_GCLK_MPEG1, 8, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_amclk, HHI_GCLK_MPEG1, 9, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_aififo2, HHI_GCLK_MPEG1, 10, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_mixer, HHI_GCLK_MPEG1, 11, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_adc, HHI_GCLK_MPEG1, 13, &gxbb_aiu_glue.hw); + /* Array of all clocks provided by this provider */ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { @@ -3100,6 +3103,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_HDMI_SEL] = &gxbb_hdmi_sel.hw, [CLKID_HDMI_DIV] = &gxbb_hdmi_div.hw, [CLKID_HDMI] = &gxbb_hdmi.hw, + [CLKID_ACODEC] = &gxl_acodec.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -3491,6 +3495,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = { &gxl_hdmi_pll_od, &gxl_hdmi_pll_od2, &gxl_hdmi_pll_dco, + &gxl_acodec, }; static const struct meson_eeclkc_data gxbb_clkc_data = { diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index b53584fe66cf..1ee8cb7e2f5a 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -188,7 +188,7 @@ #define CLKID_HDMI_SEL 203 #define CLKID_HDMI_DIV 204 -#define NR_CLKS 206 +#define NR_CLKS 207 /* include the CLKIDs that have been made part of the DT binding */ #include <dt-bindings/clock/gxbb-clkc.h> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 9fd31f23b2a9..34a70c4b4899 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -2605,14 +2605,6 @@ static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30); static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2); static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3); static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6); -static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7); -static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8); -static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9); -static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10); -static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11); -static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12); -static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13); static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14); static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15); static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16); @@ -2659,6 +2651,19 @@ static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25); static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26); static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31); +/* AIU gates */ +#define MESON_AIU_GLUE_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &meson8b_aiu_glue.hw) + +static MESON_PCLK(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6, &meson8b_aiu.hw); +static MESON_AIU_GLUE_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7); +static MESON_AIU_GLUE_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8); +static MESON_AIU_GLUE_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9); +static MESON_AIU_GLUE_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10); +static MESON_AIU_GLUE_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11); +static MESON_AIU_GLUE_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12); +static MESON_AIU_GLUE_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13); + /* Always On (AO) domain gates */ static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0); diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile index acc141adf087..14dc8a8a9d08 100644 --- a/drivers/clk/mmp/Makefile +++ b/drivers/clk/mmp/Makefile @@ -8,7 +8,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o obj-$(CONFIG_RESET_CONTROLLER) += reset.o obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o -obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o +obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c index d2cd36c54474..7a351ec65564 100644 --- a/drivers/clk/mmp/clk-mix.c +++ b/drivers/clk/mmp/clk-mix.c @@ -441,7 +441,7 @@ const struct clk_ops mmp_clk_mix_ops = { struct clk *mmp_clk_register_mix(struct device *dev, const char *name, - const char **parent_names, + const char * const *parent_names, u8 num_parents, unsigned long flags, struct mmp_clk_mix_config *config, diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c index 6e71591e63a0..52dc8b43acd9 100644 --- a/drivers/clk/mmp/clk-of-mmp2.c +++ b/drivers/clk/mmp/clk-of-mmp2.c @@ -3,6 +3,7 @@ * * Copyright (C) 2012 Marvell * Chao Xie <xiechao.mail@gmail.com> + * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -48,17 +49,39 @@ #define APMU_SDH1 0x58 #define APMU_SDH2 0xe8 #define APMU_SDH3 0xec +#define APMU_SDH4 0x15c #define APMU_USB 0x5c #define APMU_DISP0 0x4c #define APMU_DISP1 0x110 #define APMU_CCIC0 0x50 #define APMU_CCIC1 0xf4 +#define APBC_THERMAL0 0x90 +#define APBC_THERMAL1 0x98 +#define APBC_THERMAL2 0x9c +#define APBC_THERMAL3 0xa0 #define APMU_USBHSIC0 0xf8 #define APMU_USBHSIC1 0xfc -#define MPMU_UART_PLL 0x14 +#define APMU_GPU 0xcc + +#define MPMU_FCCR 0x8 +#define MPMU_POSR 0x10 +#define MPMU_UART_PLL 0x14 +#define MPMU_PLL2_CR 0x34 +/* MMP3 specific below */ +#define MPMU_PLL3_CR 0x50 +#define MPMU_PLL3_CTRL1 0x58 +#define MPMU_PLL1_CTRL 0x5c +#define MPMU_PLL_DIFF_CTRL 0x68 +#define MPMU_PLL2_CTRL1 0x414 + +enum mmp2_clk_model { + CLK_MODEL_MMP2, + CLK_MODEL_MMP3, +}; struct mmp2_clk_unit { struct mmp_clk_unit unit; + enum mmp2_clk_model model; void __iomem *mpmu_base; void __iomem *apmu_base; void __iomem *apbc_base; @@ -67,11 +90,22 @@ struct mmp2_clk_unit { static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { {MMP2_CLK_CLK32, "clk32", NULL, 0, 32768}, {MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000}, - {MMP2_CLK_PLL1, "pll1", NULL, 0, 800000000}, - {MMP2_CLK_PLL2, "pll2", NULL, 0, 960000000}, {MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000}, }; +static struct mmp_param_pll_clk pll_clks[] = { + {MMP2_CLK_PLL1, "pll1", 797330000, MPMU_FCCR, 0x4000, MPMU_POSR, 0}, + {MMP2_CLK_PLL2, "pll2", 0, MPMU_PLL2_CR, 0x0300, MPMU_PLL2_CR, 10}, +}; + +static struct mmp_param_pll_clk mmp3_pll_clks[] = { + {MMP2_CLK_PLL2, "pll1", 797330000, MPMU_FCCR, 0x4000, MPMU_POSR, 0, 26000000, MPMU_PLL1_CTRL, 25}, + {MMP2_CLK_PLL2, "pll2", 0, MPMU_PLL2_CR, 0x0300, MPMU_PLL2_CR, 10, 26000000, MPMU_PLL2_CTRL1, 25}, + {MMP3_CLK_PLL1_P, "pll1_p", 0, MPMU_PLL_DIFF_CTRL, 0x0010, 0, 0, 797330000, MPMU_PLL_DIFF_CTRL, 0}, + {MMP3_CLK_PLL2_P, "pll2_p", 0, MPMU_PLL_DIFF_CTRL, 0x0100, MPMU_PLL2_CR, 10, 26000000, MPMU_PLL_DIFF_CTRL, 5}, + {MMP3_CLK_PLL3, "pll3", 0, MPMU_PLL3_CR, 0x0300, MPMU_PLL3_CR, 10, 26000000, MPMU_PLL3_CTRL1, 25}, +}; + static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0}, {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0}, @@ -113,6 +147,16 @@ static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) mmp_register_fixed_rate_clks(unit, fixed_rate_clks, ARRAY_SIZE(fixed_rate_clks)); + if (pxa_unit->model == CLK_MODEL_MMP3) { + mmp_register_pll_clks(unit, mmp3_pll_clks, + pxa_unit->mpmu_base, + ARRAY_SIZE(mmp3_pll_clks)); + } else { + mmp_register_pll_clks(unit, pll_clks, + pxa_unit->mpmu_base, + ARRAY_SIZE(pll_clks)); + } + mmp_register_fixed_factor_clks(unit, fixed_factor_clks, ARRAY_SIZE(fixed_factor_clks)); @@ -127,16 +171,16 @@ static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) static DEFINE_SPINLOCK(uart0_lock); static DEFINE_SPINLOCK(uart1_lock); static DEFINE_SPINLOCK(uart2_lock); -static const char *uart_parent_names[] = {"uart_pll", "vctcxo"}; +static const char * const uart_parent_names[] = {"uart_pll", "vctcxo"}; static DEFINE_SPINLOCK(ssp0_lock); static DEFINE_SPINLOCK(ssp1_lock); static DEFINE_SPINLOCK(ssp2_lock); static DEFINE_SPINLOCK(ssp3_lock); -static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; +static const char * const ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; static DEFINE_SPINLOCK(timer_lock); -static const char *timer_parent_names[] = {"clk32", "vctcxo_4", "vctcxo_2", "vctcxo"}; +static const char * const timer_parent_names[] = {"clk32", "vctcxo_4", "vctcxo_2", "vctcxo"}; static DEFINE_SPINLOCK(reset_lock); @@ -176,6 +220,13 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = { {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock}, {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock}, {MMP2_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, APBC_TIMER, 0x7, 0x3, 0x0, 0, &timer_lock}, + {MMP2_CLK_THERMAL0, "thermal0_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL0, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, +}; + +static struct mmp_param_gate_clk mmp3_apbc_gate_clks[] = { + {MMP3_CLK_THERMAL1, "thermal1_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL1, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, + {MMP3_CLK_THERMAL2, "thermal2_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL2, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, + {MMP3_CLK_THERMAL3, "thermal3_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL3, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, }; static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) @@ -187,10 +238,15 @@ static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, ARRAY_SIZE(apbc_gate_clks)); + + if (pxa_unit->model == CLK_MODEL_MMP3) { + mmp_register_gate_clks(unit, mmp3_apbc_gate_clks, pxa_unit->apbc_base, + ARRAY_SIZE(mmp3_apbc_gate_clks)); + } } static DEFINE_SPINLOCK(sdh_lock); -static const char *sdh_parent_names[] = {"pll1_4", "pll2", "usb_pll", "pll1"}; +static const char * const sdh_parent_names[] = {"pll1_4", "pll2", "usb_pll", "pll1"}; static struct mmp_clk_mix_config sdh_mix_config = { .reg_info = DEFINE_MIX_REG_INFO(4, 10, 2, 8, 32), }; @@ -201,11 +257,20 @@ static DEFINE_SPINLOCK(usbhsic1_lock); static DEFINE_SPINLOCK(disp0_lock); static DEFINE_SPINLOCK(disp1_lock); -static const char *disp_parent_names[] = {"pll1", "pll1_16", "pll2", "vctcxo"}; +static const char * const disp_parent_names[] = {"pll1", "pll1_16", "pll2", "vctcxo"}; static DEFINE_SPINLOCK(ccic0_lock); static DEFINE_SPINLOCK(ccic1_lock); -static const char *ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"}; +static const char * const ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"}; + +static DEFINE_SPINLOCK(gpu_lock); +static const char * const mmp2_gpu_gc_parent_names[] = {"pll1_2", "pll1_3", "pll2_2", "pll2_3", "pll2", "usb_pll"}; +static u32 mmp2_gpu_gc_parent_table[] = { 0x0000, 0x0040, 0x0080, 0x00c0, 0x1000, 0x1040 }; +static const char * const mmp2_gpu_bus_parent_names[] = {"pll1_4", "pll2", "pll2_2", "usb_pll"}; +static u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030, 0x4020 }; +static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"}; +static const char * const mmp3_gpu_gc_parent_names[] = {"pll1", "pll2", "pll1_p", "pll2_p"}; + static struct mmp_clk_mix_config ccic0_mix_config = { .reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32), }; @@ -218,6 +283,15 @@ static struct mmp_param_mux_clk apmu_mux_clks[] = { {MMP2_CLK_DISP1_MUX, "disp1_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP1, 6, 2, 0, &disp1_lock}, }; +static struct mmp_param_mux_clk mmp3_apmu_mux_clks[] = { + {0, "gpu_bus_mux", mmp3_gpu_bus_parent_names, ARRAY_SIZE(mmp3_gpu_bus_parent_names), + CLK_SET_RATE_PARENT, APMU_GPU, 4, 2, 0, &gpu_lock}, + {0, "gpu_3d_mux", mmp3_gpu_gc_parent_names, ARRAY_SIZE(mmp3_gpu_gc_parent_names), + CLK_SET_RATE_PARENT, APMU_GPU, 6, 2, 0, &gpu_lock}, + {0, "gpu_2d_mux", mmp3_gpu_gc_parent_names, ARRAY_SIZE(mmp3_gpu_gc_parent_names), + CLK_SET_RATE_PARENT, APMU_GPU, 12, 2, 0, &gpu_lock}, +}; + static struct mmp_param_div_clk apmu_div_clks[] = { {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock}, {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock}, @@ -226,6 +300,11 @@ static struct mmp_param_div_clk apmu_div_clks[] = { {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock}, }; +static struct mmp_param_div_clk mmp3_apmu_div_clks[] = { + {0, "gpu_3d_div", "gpu_3d_mux", CLK_SET_RATE_PARENT, APMU_GPU, 24, 4, 0, &gpu_lock}, + {0, "gpu_2d_div", "gpu_2d_mux", CLK_SET_RATE_PARENT, APMU_GPU, 28, 4, 0, &gpu_lock}, +}; + static struct mmp_param_gate_clk apmu_gate_clks[] = { {MMP2_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock}, {MMP2_CLK_USBHSIC0, "usbhsic0_clk", "usb_pll", 0, APMU_USBHSIC0, 0x1b, 0x1b, 0x0, 0, &usbhsic0_lock}, @@ -235,8 +314,8 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = { {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, - {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x09, 0x09, 0x0, 0, &disp0_lock}, - {MMP2_CLK_DISP0_LCDC, "disp0_lcdc_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x12, 0x12, 0x0, 0, &disp0_lock}, + {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x12, 0x12, 0x0, 0, &disp0_lock}, + {MMP2_CLK_DISP0_LCDC, "disp0_lcdc_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x09, 0x09, 0x0, 0, &disp0_lock}, {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock}, {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x09, 0x09, 0x0, 0, &disp1_lock}, {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock}, @@ -246,6 +325,17 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = { {MMP2_CLK_CCIC1, "ccic1_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x1b, 0x1b, 0x0, 0, &ccic1_lock}, {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock}, {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock}, + {MMP2_CLK_GPU_BUS, "gpu_bus_clk", "gpu_bus_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0xa, 0xa, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, +}; + +static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = { + {MMP2_CLK_GPU_3D, "gpu_3d_clk", "gpu_3d_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0x5, 0x5, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, +}; + +static struct mmp_param_gate_clk mmp3_apmu_gate_clks[] = { + {MMP3_CLK_SDH4, "sdh4_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH4, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, + {MMP3_CLK_GPU_3D, "gpu_3d_clk", "gpu_3d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x5, 0x5, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, + {MMP3_CLK_GPU_2D, "gpu_2d_clk", "gpu_2d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x1c0000, 0x1c0000, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, }; static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit) @@ -281,6 +371,34 @@ static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit) mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, ARRAY_SIZE(apmu_gate_clks)); + + if (pxa_unit->model == CLK_MODEL_MMP3) { + mmp_register_mux_clks(unit, mmp3_apmu_mux_clks, pxa_unit->apmu_base, + ARRAY_SIZE(mmp3_apmu_mux_clks)); + + mmp_register_div_clks(unit, mmp3_apmu_div_clks, pxa_unit->apmu_base, + ARRAY_SIZE(mmp3_apmu_div_clks)); + + mmp_register_gate_clks(unit, mmp3_apmu_gate_clks, pxa_unit->apmu_base, + ARRAY_SIZE(mmp3_apmu_gate_clks)); + } else { + clk_register_mux_table(NULL, "gpu_3d_mux", mmp2_gpu_gc_parent_names, + ARRAY_SIZE(mmp2_gpu_gc_parent_names), + CLK_SET_RATE_PARENT, + pxa_unit->apmu_base + APMU_GPU, + 0, 0x10c0, 0, + mmp2_gpu_gc_parent_table, &gpu_lock); + + clk_register_mux_table(NULL, "gpu_bus_mux", mmp2_gpu_bus_parent_names, + ARRAY_SIZE(mmp2_gpu_bus_parent_names), + CLK_SET_RATE_PARENT, + pxa_unit->apmu_base + APMU_GPU, + 0, 0x4030, 0, + mmp2_gpu_bus_parent_table, &gpu_lock); + + mmp_register_gate_clks(unit, mmp2_apmu_gate_clks, pxa_unit->apmu_base, + ARRAY_SIZE(mmp2_apmu_gate_clks)); + } } static void mmp2_clk_reset_init(struct device_node *np, @@ -313,6 +431,11 @@ static void __init mmp2_clk_init(struct device_node *np) if (!pxa_unit) return; + if (of_device_is_compatible(np, "marvell,mmp3-clock")) + pxa_unit->model = CLK_MODEL_MMP3; + else + pxa_unit->model = CLK_MODEL_MMP2; + pxa_unit->mpmu_base = of_iomap(np, 0); if (!pxa_unit->mpmu_base) { pr_err("failed to map mpmu registers\n"); @@ -352,3 +475,4 @@ free_memory: } CLK_OF_DECLARE(mmp2_clk, "marvell,mmp2-clock", mmp2_clk_init); +CLK_OF_DECLARE(mmp3_clk, "marvell,mmp3-clock", mmp2_clk_init); diff --git a/drivers/clk/mmp/clk-pll.c b/drivers/clk/mmp/clk-pll.c new file mode 100644 index 000000000000..7077be293871 --- /dev/null +++ b/drivers/clk/mmp/clk-pll.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * MMP PLL clock rate calculation + * + * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk> + */ + +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> + +#include "clk.h" + +#define to_clk_mmp_pll(hw) container_of(hw, struct mmp_clk_pll, hw) + +struct mmp_clk_pll { + struct clk_hw hw; + unsigned long default_rate; + void __iomem *enable_reg; + u32 enable; + void __iomem *reg; + u8 shift; + + unsigned long input_rate; + void __iomem *postdiv_reg; + u8 postdiv_shift; +}; + +static int mmp_clk_pll_is_enabled(struct clk_hw *hw) +{ + struct mmp_clk_pll *pll = to_clk_mmp_pll(hw); + u32 val; + + val = readl_relaxed(pll->enable_reg); + if ((val & pll->enable) == pll->enable) + return 1; + + /* Some PLLs, if not software controlled, output default clock. */ + if (pll->default_rate > 0) + return 1; + + return 0; +} + +static unsigned long mmp_clk_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mmp_clk_pll *pll = to_clk_mmp_pll(hw); + u32 fbdiv, refdiv, postdiv; + u64 rate; + u32 val; + + val = readl_relaxed(pll->enable_reg); + if ((val & pll->enable) != pll->enable) + return pll->default_rate; + + if (pll->reg) { + val = readl_relaxed(pll->reg); + fbdiv = (val >> pll->shift) & 0x1ff; + refdiv = (val >> (pll->shift + 9)) & 0x1f; + } else { + fbdiv = 2; + refdiv = 1; + } + + if (pll->postdiv_reg) { + /* MMP3 clock rate calculation */ + static const u8 postdivs[] = {2, 3, 4, 5, 6, 8, 10, 12, 16}; + + val = readl_relaxed(pll->postdiv_reg); + postdiv = (val >> pll->postdiv_shift) & 0x7; + + rate = pll->input_rate; + rate *= 2 * fbdiv; + do_div(rate, refdiv); + do_div(rate, postdivs[postdiv]); + } else { + /* MMP2 clock rate calculation */ + if (refdiv == 3) { + rate = 19200000; + } else if (refdiv == 4) { + rate = 26000000; + } else { + pr_err("bad refdiv: %d (0x%08x)\n", refdiv, val); + return 0; + } + + rate *= fbdiv + 2; + do_div(rate, refdiv + 2); + } + + return (unsigned long)rate; +} + +static const struct clk_ops mmp_clk_pll_ops = { + .is_enabled = mmp_clk_pll_is_enabled, + .recalc_rate = mmp_clk_pll_recalc_rate, +}; + +struct clk *mmp_clk_register_pll(char *name, + unsigned long default_rate, + void __iomem *enable_reg, u32 enable, + void __iomem *reg, u8 shift, + unsigned long input_rate, + void __iomem *postdiv_reg, u8 postdiv_shift) +{ + struct mmp_clk_pll *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &mmp_clk_pll_ops; + init.flags = 0; + init.parent_names = NULL; + init.num_parents = 0; + + pll->default_rate = default_rate; + pll->enable_reg = enable_reg; + pll->enable = enable; + pll->reg = reg; + pll->shift = shift; + + pll->input_rate = input_rate; + pll->postdiv_reg = postdiv_reg; + pll->postdiv_shift = postdiv_shift; + + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c index ca7d37e2c7be..317123641d1e 100644 --- a/drivers/clk/mmp/clk.c +++ b/drivers/clk/mmp/clk.c @@ -176,6 +176,37 @@ void mmp_register_div_clks(struct mmp_clk_unit *unit, } } +void mmp_register_pll_clks(struct mmp_clk_unit *unit, + struct mmp_param_pll_clk *clks, + void __iomem *base, int size) +{ + struct clk *clk; + int i; + + for (i = 0; i < size; i++) { + void __iomem *reg = NULL; + + if (clks[i].offset) + reg = base + clks[i].offset; + + clk = mmp_clk_register_pll(clks[i].name, + clks[i].default_rate, + base + clks[i].enable_offset, + clks[i].enable, + reg, clks[i].shift, + clks[i].input_rate, + base + clks[i].postdiv_offset, + clks[i].postdiv_shift); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + if (clks[i].id) + unit->clk_table[clks[i].id] = clk; + } +} + void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, struct clk *clk) { diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h index 70bb73257647..971b4d6d992f 100644 --- a/drivers/clk/mmp/clk.h +++ b/drivers/clk/mmp/clk.h @@ -97,7 +97,7 @@ struct mmp_clk_mix { extern const struct clk_ops mmp_clk_mix_ops; extern struct clk *mmp_clk_register_mix(struct device *dev, const char *name, - const char **parent_names, + const char * const *parent_names, u8 num_parents, unsigned long flags, struct mmp_clk_mix_config *config, @@ -124,9 +124,6 @@ extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name, u32 val_disable, unsigned int gate_flags, spinlock_t *lock); - -extern struct clk *mmp_clk_register_pll2(const char *name, - const char *parent_name, unsigned long flags); extern struct clk *mmp_clk_register_apbc(const char *name, const char *parent_name, void __iomem *base, unsigned int delay, unsigned int apbc_flags, spinlock_t *lock); @@ -196,7 +193,7 @@ void mmp_register_gate_clks(struct mmp_clk_unit *unit, struct mmp_param_mux_clk { unsigned int id; char *name; - const char **parent_name; + const char * const *parent_name; u8 num_parents; unsigned long flags; unsigned long offset; @@ -224,6 +221,30 @@ void mmp_register_div_clks(struct mmp_clk_unit *unit, struct mmp_param_div_clk *clks, void __iomem *base, int size); +struct mmp_param_pll_clk { + unsigned int id; + char *name; + unsigned long default_rate; + unsigned long enable_offset; + u32 enable; + unsigned long offset; + u8 shift; + /* MMP3 specific: */ + unsigned long input_rate; + unsigned long postdiv_offset; + unsigned long postdiv_shift; +}; +void mmp_register_pll_clks(struct mmp_clk_unit *unit, + struct mmp_param_pll_clk *clks, + void __iomem *base, int size); + +extern struct clk *mmp_clk_register_pll(char *name, + unsigned long default_rate, + void __iomem *enable_reg, u32 enable, + void __iomem *reg, u8 shift, + unsigned long input_rate, + void __iomem *postdiv_reg, u8 postdiv_shift); + #define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \ { \ .width_div = (w_d), \ diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 15cdcdc9b3b8..11ec6f466467 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -280,6 +280,15 @@ config SC_GPUCC_7180 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config SC_MSS_7180 + tristate "SC7180 Modem Clock Controller" + select SC_GCC_7180 + help + Support for the Modem Subsystem clock controller on Qualcomm + Technologies, Inc on SC7180 devices. + Say Y if you want to use the Modem branch clocks of the Modem + subsystem clock controller to reset the MSS subsystem. + config SC_VIDEOCC_7180 tristate "SC7180 Video Clock Controller" select SC_GCC_7180 @@ -366,6 +375,13 @@ config SM_GCC_8150 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. +config SM_GCC_8250 + tristate "SM8250 Global Clock Controller" + help + Support for the global clock controller on SM8250 devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on SPMI || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 656a87e629d4..691efbf7e81f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o @@ -59,6 +60,7 @@ obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o +obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o obj-$(CONFIG_QCOM_HFPLL) += hfpll.o diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 7c2936da9b14..9b2dfa08acb2 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -52,6 +52,7 @@ #define PLL_CONFIG_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1]) #define PLL_TEST_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL]) #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U]) +#define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1]) #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS]) #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE]) #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC]) @@ -116,6 +117,22 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_ALPHA_VAL] = 0x40, [PLL_OFF_CAL_VAL] = 0x44, }, + [CLK_ALPHA_PLL_TYPE_LUCID] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_CAL_L_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_USER_CTL_U] = 0x10, + [PLL_OFF_USER_CTL_U1] = 0x14, + [PLL_OFF_CONFIG_CTL] = 0x18, + [PLL_OFF_CONFIG_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL_U1] = 0x20, + [PLL_OFF_TEST_CTL] = 0x24, + [PLL_OFF_TEST_CTL_U] = 0x28, + [PLL_OFF_TEST_CTL_U1] = 0x2c, + [PLL_OFF_STATUS] = 0x30, + [PLL_OFF_OPMODE] = 0x38, + [PLL_OFF_ALPHA_VAL] = 0x40, + }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -134,15 +151,14 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); #define PLL_HUAYRA_N_MASK 0xff #define PLL_HUAYRA_ALPHA_WIDTH 16 -#define FABIA_OPMODE_STANDBY 0x0 -#define FABIA_OPMODE_RUN 0x1 - -#define FABIA_PLL_OUT_MASK 0x7 -#define FABIA_PLL_RATE_MARGIN 500 +#define PLL_STANDBY 0x0 +#define PLL_RUN 0x1 +#define PLL_OUT_MASK 0x7 +#define PLL_RATE_MARGIN 500 -#define TRION_PLL_STANDBY 0x0 -#define TRION_PLL_RUN 0x1 -#define TRION_PLL_OUT_MASK 0x7 +/* LUCID PLL specific settings and offsets */ +#define LUCID_PLL_CAL_VAL 0x44 +#define LUCID_PCAL_DONE BIT(26) #define pll_alpha_width(p) \ ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \ @@ -544,7 +560,8 @@ static int __clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate, rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); vco = alpha_pll_find_vco(pll, rate); if (pll->vco_table && !vco) { - pr_err("alpha pll not in a valid vco range\n"); + pr_err("%s: alpha pll not in a valid vco range\n", + clk_hw_get_name(hw)); return -EINVAL; } @@ -722,7 +739,7 @@ static int alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate, */ if (clk_alpha_pll_is_enabled(hw)) { if (cur_alpha != a) { - pr_err("clock needs to be gated %s\n", + pr_err("%s: clock needs to be gated\n", clk_hw_get_name(hw)); return -EBUSY; } @@ -765,7 +782,7 @@ static int trion_pll_is_enabled(struct clk_alpha_pll *pll, if (ret) return 0; - return ((opmode_regval & TRION_PLL_RUN) && (mode_regval & PLL_OUTCTRL)); + return ((opmode_regval & PLL_RUN) && (mode_regval & PLL_OUTCTRL)); } static int clk_trion_pll_is_enabled(struct clk_hw *hw) @@ -795,7 +812,7 @@ static int clk_trion_pll_enable(struct clk_hw *hw) } /* Set operation mode to RUN */ - regmap_write(regmap, PLL_OPMODE(pll), TRION_PLL_RUN); + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); ret = wait_for_pll_enable_lock(pll); if (ret) @@ -803,7 +820,7 @@ static int clk_trion_pll_enable(struct clk_hw *hw) /* Enable the PLL outputs */ ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), - TRION_PLL_OUT_MASK, TRION_PLL_OUT_MASK); + PLL_OUT_MASK, PLL_OUT_MASK); if (ret) return ret; @@ -836,12 +853,12 @@ static void clk_trion_pll_disable(struct clk_hw *hw) /* Disable the PLL outputs */ ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), - TRION_PLL_OUT_MASK, 0); + PLL_OUT_MASK, 0); if (ret) return; /* Place the PLL mode in STANDBY */ - regmap_write(regmap, PLL_OPMODE(pll), TRION_PLL_STANDBY); + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); } @@ -849,33 +866,12 @@ static unsigned long clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - struct regmap *regmap = pll->clkr.regmap; - u32 l, frac; - u64 prate = parent_rate; - - regmap_read(regmap, PLL_L_VAL(pll), &l); - regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); - - return alpha_pll_calc_rate(prate, l, frac, ALPHA_REG_16BIT_WIDTH); -} - -static long clk_trion_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - unsigned long min_freq, max_freq; - u32 l; - u64 a; - - rate = alpha_pll_round_rate(rate, *prate, - &l, &a, ALPHA_REG_16BIT_WIDTH); - if (!pll->vco_table || alpha_pll_find_vco(pll, rate)) - return rate; + u32 l, frac, alpha_width = pll_alpha_width(pll); - min_freq = pll->vco_table[0].min_freq; - max_freq = pll->vco_table[pll->num_vco - 1].max_freq; + regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); + regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac); - return clamp(rate, min_freq, max_freq); + return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); } const struct clk_ops clk_alpha_pll_fixed_ops = { @@ -921,7 +917,7 @@ const struct clk_ops clk_trion_fixed_pll_ops = { .disable = clk_trion_pll_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_trion_pll_round_rate, + .round_rate = clk_alpha_pll_round_rate, }; EXPORT_SYMBOL_GPL(clk_trion_fixed_pll_ops); @@ -1088,14 +1084,14 @@ static int alpha_pll_fabia_enable(struct clk_hw *hw) return ret; /* Skip If PLL is already running */ - if ((opmode_val & FABIA_OPMODE_RUN) && (val & PLL_OUTCTRL)) + if ((opmode_val & PLL_RUN) && (val & PLL_OUTCTRL)) return 0; ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); if (ret) return ret; - ret = regmap_write(regmap, PLL_OPMODE(pll), FABIA_OPMODE_STANDBY); + ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); if (ret) return ret; @@ -1104,7 +1100,7 @@ static int alpha_pll_fabia_enable(struct clk_hw *hw) if (ret) return ret; - ret = regmap_write(regmap, PLL_OPMODE(pll), FABIA_OPMODE_RUN); + ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); if (ret) return ret; @@ -1113,7 +1109,7 @@ static int alpha_pll_fabia_enable(struct clk_hw *hw) return ret; ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), - FABIA_PLL_OUT_MASK, FABIA_PLL_OUT_MASK); + PLL_OUT_MASK, PLL_OUT_MASK); if (ret) return ret; @@ -1143,13 +1139,12 @@ static void alpha_pll_fabia_disable(struct clk_hw *hw) return; /* Disable main outputs */ - ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), FABIA_PLL_OUT_MASK, - 0); + ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0); if (ret) return; /* Place the PLL in STANDBY */ - regmap_write(regmap, PLL_OPMODE(pll), FABIA_OPMODE_STANDBY); + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); } static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw, @@ -1170,7 +1165,7 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l, alpha_width = pll_alpha_width(pll); u64 a; - unsigned long rrate; + unsigned long rrate, max = rate + PLL_RATE_MARGIN; rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); @@ -1178,8 +1173,9 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, * Due to limited number of bits for fractional rate programming, the * rounded up rate could be marginally higher than the requested rate. */ - if (rrate > (rate + FABIA_PLL_RATE_MARGIN) || rrate < rate) { - pr_err("Call set rate on the PLL with rounded rates!\n"); + if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { + pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", + clk_hw_get_name(hw), rrate, rate, max); return -EINVAL; } @@ -1196,6 +1192,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) struct clk_hw *parent_hw; unsigned long cal_freq, rrate; u32 cal_l, val, alpha_width = pll_alpha_width(pll); + const char *name = clk_hw_get_name(hw); u64 a; int ret; @@ -1210,7 +1207,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw)); if (!vco) { - pr_err("alpha pll: not in a valid vco range\n"); + pr_err("%s: alpha pll not in a valid vco range\n", name); return -EINVAL; } @@ -1227,7 +1224,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) * Due to a limited number of bits for fractional rate programming, the * rounded up rate could be marginally higher than the requested rate. */ - if (rrate > (cal_freq + FABIA_PLL_RATE_MARGIN) || rrate < cal_freq) + if (rrate > (cal_freq + PLL_RATE_MARGIN) || rrate < cal_freq) return -EINVAL; /* Setup PLL for calibration frequency */ @@ -1236,7 +1233,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) /* Bringup the PLL at calibration frequency */ ret = clk_alpha_pll_enable(hw); if (ret) { - pr_err("alpha pll calibration failed\n"); + pr_err("%s: alpha pll calibration failed\n", name); return ret; } @@ -1394,3 +1391,175 @@ const struct clk_ops clk_alpha_pll_postdiv_fabia_ops = { .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops); + +/** + * clk_lucid_pll_configure - configure the lucid pll + * + * @pll: clk alpha pll + * @regmap: register map + * @config: configuration to apply for pll + */ +void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + if (config->l) + regmap_write(regmap, PLL_L_VAL(pll), config->l); + + regmap_write(regmap, PLL_CAL_L_VAL(pll), LUCID_PLL_CAL_VAL); + + if (config->alpha) + regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); + + if (config->config_ctl_val) + regmap_write(regmap, PLL_CONFIG_CTL(pll), + config->config_ctl_val); + + if (config->config_ctl_hi_val) + regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + + if (config->config_ctl_hi1_val) + regmap_write(regmap, PLL_CONFIG_CTL_U1(pll), + config->config_ctl_hi1_val); + + if (config->user_ctl_val) + regmap_write(regmap, PLL_USER_CTL(pll), + config->user_ctl_val); + + if (config->user_ctl_hi_val) + regmap_write(regmap, PLL_USER_CTL_U(pll), + config->user_ctl_hi_val); + + if (config->user_ctl_hi1_val) + regmap_write(regmap, PLL_USER_CTL_U1(pll), + config->user_ctl_hi1_val); + + if (config->test_ctl_val) + regmap_write(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + + if (config->test_ctl_hi_val) + regmap_write(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); + + if (config->test_ctl_hi1_val) + regmap_write(regmap, PLL_TEST_CTL_U1(pll), + config->test_ctl_hi1_val); + + regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS, + PLL_UPDATE_BYPASS); + + /* Disable PLL output */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); + + /* Set operation mode to OFF */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); + + /* Place the PLL in STANDBY mode */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); +} +EXPORT_SYMBOL_GPL(clk_lucid_pll_configure); + +/* + * The Lucid PLL requires a power-on self-calibration which happens when the + * PLL comes out of reset. Calibrate in case it is not completed. + */ +static int alpha_pll_lucid_prepare(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 regval; + int ret; + + /* Return early if calibration is not needed. */ + regmap_read(pll->clkr.regmap, PLL_STATUS(pll), ®val); + if (regval & LUCID_PCAL_DONE) + return 0; + + /* On/off to calibrate */ + ret = clk_trion_pll_enable(hw); + if (!ret) + clk_trion_pll_disable(hw); + + return ret; +} + +static int alpha_pll_lucid_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + unsigned long rrate; + u32 regval, l, alpha_width = pll_alpha_width(pll); + u64 a; + int ret; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + + /* + * Due to a limited number of bits for fractional rate programming, the + * rounded up rate could be marginally higher than the requested rate. + */ + if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { + pr_err("Call set rate on the PLL with rounded rates!\n"); + return -EINVAL; + } + + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + + /* Latch the PLL input */ + ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), + PLL_UPDATE, PLL_UPDATE); + if (ret) + return ret; + + /* Wait for 2 reference cycles before checking the ACK bit. */ + udelay(1); + regmap_read(pll->clkr.regmap, PLL_MODE(pll), ®val); + if (!(regval & ALPHA_PLL_ACK_LATCH)) { + pr_err("Lucid PLL latch failed. Output may be unstable!\n"); + return -EINVAL; + } + + /* Return the latch input to 0 */ + ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), + PLL_UPDATE, 0); + if (ret) + return ret; + + if (clk_hw_is_enabled(hw)) { + ret = wait_for_pll_enable_lock(pll); + if (ret) + return ret; + } + + /* Wait for PLL output to stabilize */ + udelay(100); + return 0; +} + +const struct clk_ops clk_alpha_pll_lucid_ops = { + .prepare = alpha_pll_lucid_prepare, + .enable = clk_trion_pll_enable, + .disable = clk_trion_pll_disable, + .is_enabled = clk_trion_pll_is_enabled, + .recalc_rate = clk_trion_pll_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = alpha_pll_lucid_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops); + +const struct clk_ops clk_alpha_pll_fixed_lucid_ops = { + .enable = clk_trion_pll_enable, + .disable = clk_trion_pll_disable, + .is_enabled = clk_trion_pll_is_enabled, + .recalc_rate = clk_trion_pll_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_ops); + +const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { + .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, + .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, + .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index fbc1f67c7a26..704674a153b6 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -14,6 +14,7 @@ enum { CLK_ALPHA_PLL_TYPE_BRAMMO, CLK_ALPHA_PLL_TYPE_FABIA, CLK_ALPHA_PLL_TYPE_TRION, + CLK_ALPHA_PLL_TYPE_LUCID, CLK_ALPHA_PLL_TYPE_MAX, }; @@ -30,6 +31,7 @@ enum { PLL_OFF_CONFIG_CTL_U1, PLL_OFF_TEST_CTL, PLL_OFF_TEST_CTL_U, + PLL_OFF_TEST_CTL_U1, PLL_OFF_STATUS, PLL_OFF_OPMODE, PLL_OFF_FRAC, @@ -94,10 +96,13 @@ struct alpha_pll_config { u32 alpha_hi; u32 config_ctl_val; u32 config_ctl_hi_val; + u32 config_ctl_hi1_val; u32 user_ctl_val; u32 user_ctl_hi_val; + u32 user_ctl_hi1_val; u32 test_ctl_val; u32 test_ctl_hi_val; + u32 test_ctl_hi1_val; u32 main_output_mask; u32 aux_output_mask; u32 aux2_output_mask; @@ -123,10 +128,17 @@ extern const struct clk_ops clk_alpha_pll_fabia_ops; extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops; extern const struct clk_ops clk_alpha_pll_postdiv_fabia_ops; +extern const struct clk_ops clk_alpha_pll_lucid_ops; +extern const struct clk_ops clk_alpha_pll_fixed_lucid_ops; +extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops; + void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); +void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config); + extern const struct clk_ops clk_trion_fixed_pll_ops; extern const struct clk_ops clk_trion_pll_postdiv_ops; diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c index 9e3110a71f12..f71d228fd6bd 100644 --- a/drivers/clk/qcom/clk-rpm.c +++ b/drivers/clk/qcom/clk-rpm.c @@ -543,10 +543,45 @@ static const struct rpm_clk_desc rpm_clk_apq8064 = { .num_clks = ARRAY_SIZE(apq8064_clks), }; +/* ipq806x */ +DEFINE_CLK_RPM(ipq806x, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK); +DEFINE_CLK_RPM(ipq806x, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK); +DEFINE_CLK_RPM(ipq806x, daytona_clk, daytona_a_clk, QCOM_RPM_DAYTONA_FABRIC_CLK); +DEFINE_CLK_RPM(ipq806x, ebi1_clk, ebi1_a_clk, QCOM_RPM_EBI1_CLK); +DEFINE_CLK_RPM(ipq806x, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK); +DEFINE_CLK_RPM(ipq806x, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK); +DEFINE_CLK_RPM(ipq806x, nss_fabric_0_clk, nss_fabric_0_a_clk, QCOM_RPM_NSS_FABRIC_0_CLK); +DEFINE_CLK_RPM(ipq806x, nss_fabric_1_clk, nss_fabric_1_a_clk, QCOM_RPM_NSS_FABRIC_1_CLK); + +static struct clk_rpm *ipq806x_clks[] = { + [RPM_APPS_FABRIC_CLK] = &ipq806x_afab_clk, + [RPM_APPS_FABRIC_A_CLK] = &ipq806x_afab_a_clk, + [RPM_CFPB_CLK] = &ipq806x_cfpb_clk, + [RPM_CFPB_A_CLK] = &ipq806x_cfpb_a_clk, + [RPM_DAYTONA_FABRIC_CLK] = &ipq806x_daytona_clk, + [RPM_DAYTONA_FABRIC_A_CLK] = &ipq806x_daytona_a_clk, + [RPM_EBI1_CLK] = &ipq806x_ebi1_clk, + [RPM_EBI1_A_CLK] = &ipq806x_ebi1_a_clk, + [RPM_SYS_FABRIC_CLK] = &ipq806x_sfab_clk, + [RPM_SYS_FABRIC_A_CLK] = &ipq806x_sfab_a_clk, + [RPM_SFPB_CLK] = &ipq806x_sfpb_clk, + [RPM_SFPB_A_CLK] = &ipq806x_sfpb_a_clk, + [RPM_NSS_FABRIC_0_CLK] = &ipq806x_nss_fabric_0_clk, + [RPM_NSS_FABRIC_0_A_CLK] = &ipq806x_nss_fabric_0_a_clk, + [RPM_NSS_FABRIC_1_CLK] = &ipq806x_nss_fabric_1_clk, + [RPM_NSS_FABRIC_1_A_CLK] = &ipq806x_nss_fabric_1_a_clk, +}; + +static const struct rpm_clk_desc rpm_clk_ipq806x = { + .clks = ipq806x_clks, + .num_clks = ARRAY_SIZE(ipq806x_clks), +}; + static const struct of_device_id rpm_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8660", .data = &rpm_clk_msm8660 }, { .compatible = "qcom,rpmcc-apq8060", .data = &rpm_clk_msm8660 }, { .compatible = "qcom,rpmcc-apq8064", .data = &rpm_clk_apq8064 }, + { .compatible = "qcom,rpmcc-ipq806x", .data = &rpm_clk_ipq806x }, { } }; MODULE_DEVICE_TABLE(of, rpm_clk_match_table); diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 98a118c1e244..e2c669b08aff 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include <linux/clk-provider.h> @@ -143,12 +143,22 @@ static inline bool has_state_changed(struct clk_rpmh *c, u32 state) != (c->aggr_state & BIT(state)); } +static int clk_rpmh_send(struct clk_rpmh *c, enum rpmh_state state, + struct tcs_cmd *cmd, bool wait) +{ + if (wait) + return rpmh_write(c->dev, state, cmd, 1); + + return rpmh_write_async(c->dev, state, cmd, 1); +} + static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c) { struct tcs_cmd cmd = { 0 }; u32 cmd_state, on_val; enum rpmh_state state = RPMH_SLEEP_STATE; int ret; + bool wait; cmd.addr = c->res_addr; cmd_state = c->aggr_state; @@ -159,7 +169,8 @@ static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c) if (cmd_state & BIT(state)) cmd.data = on_val; - ret = rpmh_write_async(c->dev, state, &cmd, 1); + wait = cmd_state && state == RPMH_ACTIVE_ONLY_STATE; + ret = clk_rpmh_send(c, state, &cmd, wait); if (ret) { dev_err(c->dev, "set %s state of %s failed: (%d)\n", !state ? "sleep" : @@ -216,7 +227,7 @@ static int clk_rpmh_prepare(struct clk_hw *hw) mutex_unlock(&rpmh_clk_lock); return ret; -}; +} static void clk_rpmh_unprepare(struct clk_hw *hw) { @@ -248,38 +259,33 @@ static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) { struct tcs_cmd cmd = { 0 }; u32 cmd_state; - int ret; + int ret = 0; mutex_lock(&rpmh_clk_lock); - - cmd_state = 0; if (enable) { cmd_state = 1; if (c->aggr_state) cmd_state = c->aggr_state; + } else { + cmd_state = 0; } - if (c->last_sent_aggr_state == cmd_state) { - mutex_unlock(&rpmh_clk_lock); - return 0; - } + if (c->last_sent_aggr_state != cmd_state) { + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state); - cmd.addr = c->res_addr; - cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state); - - ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1); - if (ret) { - dev_err(c->dev, "set active state of %s failed: (%d)\n", - c->res_name, ret); - mutex_unlock(&rpmh_clk_lock); - return ret; + ret = clk_rpmh_send(c, RPMH_ACTIVE_ONLY_STATE, &cmd, enable); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + } else { + c->last_sent_aggr_state = cmd_state; + } } - c->last_sent_aggr_state = cmd_state; - mutex_unlock(&rpmh_clk_lock); - return 0; + return ret; } static int clk_rpmh_bcm_prepare(struct clk_hw *hw) @@ -287,14 +293,14 @@ static int clk_rpmh_bcm_prepare(struct clk_hw *hw) struct clk_rpmh *c = to_clk_rpmh(hw); return clk_rpmh_bcm_send_cmd(c, true); -}; +} static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) { struct clk_rpmh *c = to_clk_rpmh(hw); clk_rpmh_bcm_send_cmd(c, false); -}; +} static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -310,7 +316,7 @@ static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, clk_rpmh_bcm_send_cmd(c, true); return 0; -}; +} static long clk_rpmh_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) @@ -404,6 +410,28 @@ static const struct clk_rpmh_desc clk_rpmh_sc7180 = { .num_clks = ARRAY_SIZE(sc7180_rpmh_clocks), }; +DEFINE_CLK_RPMH_VRM(sm8250, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 2); + +static struct clk_hw *sm8250_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK1] = &sm8250_ln_bb_clk1.hw, + [RPMH_LN_BB_CLK1_A] = &sm8250_ln_bb_clk1_ao.hw, + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, + [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, + [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, + [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, + [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, + [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sm8250 = { + .clks = sm8250_rpmh_clocks, + .num_clks = ARRAY_SIZE(sm8250_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -490,6 +518,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, + { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250}, { } }; MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 0bbfef9fa6de..52f63ad787ba 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -525,6 +525,55 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8974 = { .num_clks = ARRAY_SIZE(msm8974_clks), }; + +/* msm8976 */ +DEFINE_CLK_SMD_RPM(msm8976, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); +DEFINE_CLK_SMD_RPM(msm8976, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); +DEFINE_CLK_SMD_RPM(msm8976, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, + QCOM_SMD_RPM_BUS_CLK, 2); +DEFINE_CLK_SMD_RPM(msm8976, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); +DEFINE_CLK_SMD_RPM(msm8976, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); +DEFINE_CLK_SMD_RPM_QDSS(msm8976, qdss_clk, qdss_a_clk, + QCOM_SMD_RPM_MISC_CLK, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, bb_clk1, bb_clk1_a, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, bb_clk2, bb_clk2_a, 2); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, rf_clk2, rf_clk2_a, 5); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, div_clk2, div_clk2_a, 12); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8976, bb_clk1_pin, bb_clk1_a_pin, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8976, bb_clk2_pin, bb_clk2_a_pin, 2); + +static struct clk_smd_rpm *msm8976_clks[] = { + [RPM_SMD_PCNOC_CLK] = &msm8976_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8976_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8976_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8976_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8976_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8976_bimc_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8976_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8976_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &msm8976_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8976_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &msm8976_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8976_bb_clk2_a, + [RPM_SMD_RF_CLK2] = &msm8976_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8976_rf_clk2_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8976_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8976_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &msm8976_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8976_bb_clk2_a_pin, + [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8976_mmssnoc_ahb_clk, + [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8976_mmssnoc_ahb_a_clk, + [RPM_SMD_DIV_CLK2] = &msm8976_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &msm8976_div_clk2_a, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, +}; + +static const struct rpm_smd_clk_desc rpm_clk_msm8976 = { + .clks = msm8976_clks, + .num_clks = ARRAY_SIZE(msm8976_clks), +}; + /* msm8996 */ DEFINE_CLK_SMD_RPM(msm8996, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); DEFINE_CLK_SMD_RPM(msm8996, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); @@ -720,6 +769,7 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, + { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 }, { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 }, { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 }, { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index b0eee0903807..a8456e09c44d 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c @@ -1224,6 +1224,8 @@ static struct clk_rcg prng_src = { .parent_map = gcc_pxo_pll8_map, }, .clkr = { + .enable_reg = 0x2e80, + .enable_mask = BIT(11), .hw.init = &(struct clk_init_data){ .name = "prng_src", .parent_names = gcc_pxo_pll8, diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 7f59fb8da033..6a51b5b5fc19 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include <linux/clk-provider.h> @@ -2165,6 +2165,71 @@ static struct clk_branch gcc_video_xo_clk = { }, }; +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mfab_axis_clk = { + .halt_reg = 0x8a004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mfab_axis_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_nav_axi_clk = { + .halt_reg = 0x8a00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8a00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_nav_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a150, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a150, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_memnoc_axi_clk = { + .halt_reg = 0x8a154, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_memnoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc ufs_phy_gdsc = { .gdscr = 0x77004, .pd = { @@ -2336,6 +2401,11 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { [GPLL7] = &gpll7.clkr, [GPLL4] = &gpll4.clkr, [GPLL1] = &gpll1.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_MFAB_AXIS_CLK] = &gcc_mss_mfab_axis_clk.clkr, + [GCC_MSS_NAV_AXI_CLK] = &gcc_mss_nav_axi_clk.clkr, + [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, }; static const struct qcom_reset_map gcc_sc7180_resets[] = { diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c index 20877214acff..ef98fdc51755 100644 --- a/drivers/clk/qcom/gcc-sm8150.c +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -21,6 +21,7 @@ #include "clk-rcg.h" #include "clk-regmap.h" #include "reset.h" +#include "gdsc.h" enum { P_BI_TCXO, @@ -3171,6 +3172,18 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { }, }; +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0xf058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_sec_clkref_clk = { .halt_reg = 0x8c028, .halt_check = BRANCH_HALT, @@ -3218,6 +3231,18 @@ static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { }, }; +static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x10058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + /* * Clock ON depends on external parent 'config noc', so cant poll * delay and also mark as crtitical for video boot @@ -3292,6 +3317,24 @@ static struct clk_branch gcc_video_xo_clk = { }, }; +static struct gdsc usb30_prim_gdsc = { + .gdscr = 0xf004, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR, +}; + +static struct gdsc usb30_sec_gdsc = { + .gdscr = 0x10004, + .pd = { + .name = "usb30_sec_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR, +}; + static struct clk_regmap *gcc_sm8150_clocks[] = { [GCC_AGGRE_NOC_PCIE_TBU_CLK] = &gcc_aggre_noc_pcie_tbu_clk.clkr, [GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr, @@ -3480,10 +3523,12 @@ static struct clk_regmap *gcc_sm8150_clocks[] = { [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, [GCC_USB3_SEC_CLKREF_CLK] = &gcc_usb3_sec_clkref_clk.clkr, [GCC_USB3_SEC_PHY_AUX_CLK] = &gcc_usb3_sec_phy_aux_clk.clkr, [GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &gcc_usb3_sec_phy_aux_clk_src.clkr, [GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr, + [GCC_USB3_SEC_PHY_PIPE_CLK] = &gcc_usb3_sec_phy_pipe_clk.clkr, [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr, [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, @@ -3527,6 +3572,11 @@ static const struct qcom_reset_map gcc_sm8150_resets[] = { [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, }; +static struct gdsc *gcc_sm8150_gdscs[] = { + [USB30_PRIM_GDSC] = &usb30_prim_gdsc, + [USB30_SEC_GDSC] = &usb30_sec_gdsc, +}; + static const struct regmap_config gcc_sm8150_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -3541,6 +3591,8 @@ static const struct qcom_cc_desc gcc_sm8150_desc = { .num_clks = ARRAY_SIZE(gcc_sm8150_clocks), .resets = gcc_sm8150_resets, .num_resets = ARRAY_SIZE(gcc_sm8150_resets), + .gdscs = gcc_sm8150_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sm8150_gdscs), }; static const struct of_device_id gcc_sm8150_match_table[] = { diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c new file mode 100644 index 000000000000..6cb6617b8d88 --- /dev/null +++ b/drivers/clk/qcom/gcc-sm8250.c @@ -0,0 +1,3690 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,gcc-sm8250.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_AUD_REF_CLK, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_GPLL9_OUT_MAIN, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x76000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll9 = { + .offset = 0x1c000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gpll9", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct clk_parent_data gcc_parent_data_0_ao[] = { + { .fw_name = "bi_tcxo_ao" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk" }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL9_OUT_MAIN, 2 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_AUD_REF_CLK, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "aud_ref_clk" }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .cmd_rcgr = 0x48010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk_src", + .parent_data = gcc_parent_data_0_ao, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0x6b038, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_1_aux_clk_src = { + .cmd_rcgr = 0x8d038, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_2_aux_clk_src = { + .cmd_rcgr = 0x6038, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_phy_refgen_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { + .cmd_rcgr = 0x6f014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_refgen_clk_src", + .parent_data = gcc_parent_data_0_ao, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x17010, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x17140, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x17270, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x173a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x174d0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x17600, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { + .cmd_rcgr = 0x17730, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { + .cmd_rcgr = 0x17860, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18010, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18140, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { + .cmd_rcgr = 0x18270, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x183a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x184d0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18600, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .name = "gcc_qupv3_wrap2_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { + .cmd_rcgr = 0x1e010, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .name = "gcc_qupv3_wrap2_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { + .cmd_rcgr = 0x1e140, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .name = "gcc_qupv3_wrap2_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { + .cmd_rcgr = 0x1e270, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .name = "gcc_qupv3_wrap2_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { + .cmd_rcgr = 0x1e3a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .name = "gcc_qupv3_wrap2_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { + .cmd_rcgr = 0x1e4d0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .name = "gcc_qupv3_wrap2_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { + .cmd_rcgr = 0x1e600, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1400c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x1600c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_tsif_ref_clk_src[] = { + F(105495, P_BI_TCXO, 2, 1, 91), + { } +}; + +static struct clk_rcg2 gcc_tsif_ref_clk_src = { + .cmd_rcgr = 0x36010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_tsif_ref_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ref_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_axi_clk_src = { + .cmd_rcgr = 0x75024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_ice_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_ice_core_clk_src = { + .cmd_rcgr = 0x7506c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_phy_aux_clk_src = { + .cmd_rcgr = 0x750a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = 1, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_unipro_core_clk_src = { + .cmd_rcgr = 0x75084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_unipro_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x7706c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x770a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = 1, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x77084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(33333333, P_GPLL0_OUT_EVEN, 9, 0, 0), + F(66666667, P_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0xf020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0xf038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_sec_master_clk_src = { + .cmd_rcgr = 0x10020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = { + .cmd_rcgr = 0x10038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0xf064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { + .cmd_rcgr = 0x10064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div gcc_cpuss_ahb_postdiv_clk_src = { + .reg = 0x48028, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gcc_cpuss_ahb_postdiv_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0xf050, + .shift = 0, + .width = 2, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_sec_mock_utmi_postdiv_clk_src = { + .reg = 0x10050, + .shift = 0, + .width = 2, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gcc_usb30_sec_mock_utmi_postdiv_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_sec_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_tbu_clk = { + .halt_reg = 0x9000c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9000c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_noc_pcie_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_card_axi_clk = { + .halt_reg = 0x750cc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x750cc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x750cc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_card_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_card_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x770cc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770cc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770cc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0xf080, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xf080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_sec_axi_clk = { + .halt_reg = 0x10080, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x10080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_usb3_sec_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0xb02c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_sf_axi_clk = { + .halt_reg = 0xb030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_xo_clk = { + .halt_reg = 0xb040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0xf07c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xf07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1007c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_sec_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_rbcpr_clk = { + .halt_reg = 0x48004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_rbcpr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x71154, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x71154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_pcie_sf_tbu_clk = { + .halt_reg = 0x8d058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8d058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ddrss_pcie_sf_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0xb034, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_sf_axi_clk = { + .halt_reg = 0xb038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_xo_clk = { + .halt_reg = 0xb044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_iref_en = { + .halt_reg = 0x8c014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_iref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x7100c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7100c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x71018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_axi_clk = { + .halt_reg = 0x4d008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_axi_clk = { + .halt_reg = 0x73008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x73008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_cfg_ahb_clk = { + .halt_reg = 0x73004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x73004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_cfg_ahb_clk = { + .halt_reg = 0x4d004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_dma_clk = { + .halt_reg = 0x4d00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4d00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_dma_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_phy_refgen_clk = { + .halt_reg = 0x6f02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_phy_refgen_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_phy_refgen_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie1_phy_refgen_clk = { + .halt_reg = 0x6f030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie1_phy_refgen_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_phy_refgen_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie2_phy_refgen_clk = { + .halt_reg = 0x6f034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie2_phy_refgen_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_phy_refgen_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x6b028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x6b024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b02c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { + .halt_reg = 0x6b010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_aux_clk = { + .halt_reg = 0x8d028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(29), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { + .halt_reg = 0x8d024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8d024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(28), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_mstr_axi_clk = { + .halt_reg = 0x8d01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_pipe_clk = { + .halt_reg = 0x8d02c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(30), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_axi_clk = { + .halt_reg = 0x8d014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8d014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_q2a_axi_clk = { + .halt_reg = 0x8d010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_aux_clk = { + .halt_reg = 0x6028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_cfg_ahb_clk = { + .halt_reg = 0x6024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_mstr_axi_clk = { + .halt_reg = 0x601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_pipe_clk = { + .halt_reg = 0x602c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_slv_axi_clk = { + .halt_reg = 0x6014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_slv_q2a_axi_clk = { + .halt_reg = 0x6010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_mdm_clkref_en = { + .halt_reg = 0x8c00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_mdm_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_aux_clk = { + .halt_reg = 0x6f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pcie_0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_wifi_clkref_en = { + .halt_reg = 0x8c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_wifi_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_wigig_clkref_en = { + .halt_reg = 0x8c008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_wigig_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0xb018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0xb01c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_ahb_clk = { + .halt_reg = 0xb020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_disp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cvp_ahb_clk = { + .halt_reg = 0xb010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_video_cvp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0xb014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x23008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x1700c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x1713c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x1726c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x1739c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x174cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x175fc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s6_clk = { + .halt_reg = 0x1772c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s6_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s7_clk = { + .halt_reg = 0x1785c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s7_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x23140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x23138, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x1800c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x1813c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x1826c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x1839c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x184cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x185fc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_2x_clk = { + .halt_reg = 0x23278, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_clk = { + .halt_reg = 0x23270, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s0_clk = { + .halt_reg = 0x1e00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap2_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s1_clk = { + .halt_reg = 0x1e13c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap2_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s2_clk = { + .halt_reg = 0x1e26c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap2_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s3_clk = { + .halt_reg = 0x1e39c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap2_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s4_clk = { + .halt_reg = 0x1e4cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap2_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s5_clk = { + .halt_reg = 0x1e5fc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap2_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x18008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x18008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_2_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = { + .halt_reg = 0x1e008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1e008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_2_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x16008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_apps_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc4_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ahb_clk = { + .halt_reg = 0x36004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x36004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_inactivity_timers_clk = { + .halt_reg = 0x3600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_inactivity_timers_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ref_clk = { + .halt_reg = 0x36008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ref_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_tsif_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_1x_clkref_en = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_1x_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_ahb_clk = { + .halt_reg = 0x75018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x75018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_axi_clk = { + .halt_reg = 0x75010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_card_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_ice_core_clk = { + .halt_reg = 0x75064, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x75064, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ice_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_card_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_phy_aux_clk = { + .halt_reg = 0x7509c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7509c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7509c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_card_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { + .halt_reg = 0x75020, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x75020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = { + .halt_reg = 0x750b8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x750b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_rx_symbol_1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_tx_symbol_0_clk = { + .halt_reg = 0x7501c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_unipro_core_clk = { + .halt_reg = 0x7505c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7505c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7505c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_unipro_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_card_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x77064, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77064, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x7709c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7709c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7709c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x77020, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_reg = 0x770b8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x770b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x7701c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7701c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x7705c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7705c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7705c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xf010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0xf01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0xf018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_master_clk = { + .halt_reg = 0x10010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x10010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_master_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_mock_utmi_clk = { + .halt_reg = 0x1001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1001c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_mock_utmi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = + &gcc_usb30_sec_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_sleep_clk = { + .halt_reg = 0x10018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0xf054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0xf058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0xf05c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xf05c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_clkref_en = { + .halt_reg = 0x8c010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_aux_clk = { + .halt_reg = 0x10054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_sec_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { + .halt_reg = 0x10058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_com_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_sec_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_reg = 0x1005c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1005c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0xb024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi1_clk = { + .halt_reg = 0xb028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_xo_clk = { + .halt_reg = 0xb03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc pcie_0_gdsc = { + .gdscr = 0x6b004, + .pd = { + .name = "pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie_1_gdsc = { + .gdscr = 0x8d004, + .pd = { + .name = "pcie_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie_2_gdsc = { + .gdscr = 0x6004, + .pd = { + .name = "pcie_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ufs_card_gdsc = { + .gdscr = 0x75004, + .pd = { + .name = "ufs_card_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ufs_phy_gdsc = { + .gdscr = 0x77004, + .pd = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc usb30_prim_gdsc = { + .gdscr = 0xf004, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc usb30_sec_gdsc = { + .gdscr = 0x10004, + .pd = { + .name = "usb30_sec_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { + .gdscr = 0x7d050, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = { + .gdscr = 0x7d058, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc = { + .gdscr = 0x7d054, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc = { + .gdscr = 0x7d06c, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct clk_regmap *gcc_sm8250_clocks[] = { + [GCC_AGGRE_NOC_PCIE_TBU_CLK] = &gcc_aggre_noc_pcie_tbu_clk.clkr, + [GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, + [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, + [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, + [GCC_CPUSS_AHB_POSTDIV_CLK_SRC] = &gcc_cpuss_ahb_postdiv_clk_src.clkr, + [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DDRSS_PCIE_SF_TBU_CLK] = &gcc_ddrss_pcie_sf_tbu_clk.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_SF_AXI_CLK] = &gcc_disp_sf_axi_clk.clkr, + [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_IREF_EN] = &gcc_gpu_iref_en.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr, + [GCC_NPU_BWMON_AXI_CLK] = &gcc_npu_bwmon_axi_clk.clkr, + [GCC_NPU_BWMON_CFG_AHB_CLK] = &gcc_npu_bwmon_cfg_ahb_clk.clkr, + [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr, + [GCC_NPU_DMA_CLK] = &gcc_npu_dma_clk.clkr, + [GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr, + [GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr, + [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr, + [GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr, + [GCC_PCIE2_PHY_REFGEN_CLK] = &gcc_pcie2_phy_refgen_clk.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr, + [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr, + [GCC_PCIE_1_AUX_CLK_SRC] = &gcc_pcie_1_aux_clk_src.clkr, + [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr, + [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr, + [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr, + [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr, + [GCC_PCIE_1_SLV_Q2A_AXI_CLK] = &gcc_pcie_1_slv_q2a_axi_clk.clkr, + [GCC_PCIE_2_AUX_CLK] = &gcc_pcie_2_aux_clk.clkr, + [GCC_PCIE_2_AUX_CLK_SRC] = &gcc_pcie_2_aux_clk_src.clkr, + [GCC_PCIE_2_CFG_AHB_CLK] = &gcc_pcie_2_cfg_ahb_clk.clkr, + [GCC_PCIE_2_MSTR_AXI_CLK] = &gcc_pcie_2_mstr_axi_clk.clkr, + [GCC_PCIE_2_PIPE_CLK] = &gcc_pcie_2_pipe_clk.clkr, + [GCC_PCIE_2_SLV_AXI_CLK] = &gcc_pcie_2_slv_axi_clk.clkr, + [GCC_PCIE_2_SLV_Q2A_AXI_CLK] = &gcc_pcie_2_slv_q2a_axi_clk.clkr, + [GCC_PCIE_MDM_CLKREF_EN] = &gcc_pcie_mdm_clkref_en.clkr, + [GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.clkr, + [GCC_PCIE_PHY_REFGEN_CLK_SRC] = &gcc_pcie_phy_refgen_clk_src.clkr, + [GCC_PCIE_WIFI_CLKREF_EN] = &gcc_pcie_wifi_clkref_en.clkr, + [GCC_PCIE_WIGIG_CLKREF_EN] = &gcc_pcie_wigig_clkref_en.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr, + [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr, + [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr, + [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr, + [GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr, + [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr, + [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr, + [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr, + [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr, + [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr, + [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr, + [GCC_QUPV3_WRAP2_S5_CLK] = &gcc_qupv3_wrap2_s5_clk.clkr, + [GCC_QUPV3_WRAP2_S5_CLK_SRC] = &gcc_qupv3_wrap2_s5_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, + [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr, + [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr, + [GCC_TSIF_REF_CLK_SRC] = &gcc_tsif_ref_clk_src.clkr, + [GCC_UFS_1X_CLKREF_EN] = &gcc_ufs_1x_clkref_en.clkr, + [GCC_UFS_CARD_AHB_CLK] = &gcc_ufs_card_ahb_clk.clkr, + [GCC_UFS_CARD_AXI_CLK] = &gcc_ufs_card_axi_clk.clkr, + [GCC_UFS_CARD_AXI_CLK_SRC] = &gcc_ufs_card_axi_clk_src.clkr, + [GCC_UFS_CARD_ICE_CORE_CLK] = &gcc_ufs_card_ice_core_clk.clkr, + [GCC_UFS_CARD_ICE_CORE_CLK_SRC] = &gcc_ufs_card_ice_core_clk_src.clkr, + [GCC_UFS_CARD_PHY_AUX_CLK] = &gcc_ufs_card_phy_aux_clk.clkr, + [GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr, + [GCC_UFS_CARD_RX_SYMBOL_0_CLK] = &gcc_ufs_card_rx_symbol_0_clk.clkr, + [GCC_UFS_CARD_RX_SYMBOL_1_CLK] = &gcc_ufs_card_rx_symbol_1_clk.clkr, + [GCC_UFS_CARD_TX_SYMBOL_0_CLK] = &gcc_ufs_card_tx_symbol_0_clk.clkr, + [GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr, + [GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_card_unipro_core_clk_src.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB30_SEC_MASTER_CLK] = &gcc_usb30_sec_master_clk.clkr, + [GCC_USB30_SEC_MASTER_CLK_SRC] = &gcc_usb30_sec_master_clk_src.clkr, + [GCC_USB30_SEC_MOCK_UTMI_CLK] = &gcc_usb30_sec_mock_utmi_clk.clkr, + [GCC_USB30_SEC_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_sec_mock_utmi_clk_src.clkr, + [GCC_USB30_SEC_MOCK_UTMI_POSTDIV_CLK_SRC] = + &gcc_usb30_sec_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_SEC_SLEEP_CLK] = &gcc_usb30_sec_sleep_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_SEC_CLKREF_EN] = &gcc_usb3_sec_clkref_en.clkr, + [GCC_USB3_SEC_PHY_AUX_CLK] = &gcc_usb3_sec_phy_aux_clk.clkr, + [GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &gcc_usb3_sec_phy_aux_clk_src.clkr, + [GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr, + [GCC_USB3_SEC_PHY_PIPE_CLK] = &gcc_usb3_sec_phy_pipe_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL9] = &gpll9.clkr, +}; + +static struct gdsc *gcc_sm8250_gdscs[] = { + [PCIE_0_GDSC] = &pcie_0_gdsc, + [PCIE_1_GDSC] = &pcie_1_gdsc, + [PCIE_2_GDSC] = &pcie_2_gdsc, + [UFS_CARD_GDSC] = &ufs_card_gdsc, + [UFS_PHY_GDSC] = &ufs_phy_gdsc, + [USB30_PRIM_GDSC] = &usb30_prim_gdsc, + [USB30_SEC_GDSC] = &usb30_sec_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc, +}; + +static const struct qcom_reset_map gcc_sm8250_resets[] = { + [GCC_GPU_BCR] = { 0x71000 }, + [GCC_MMSS_BCR] = { 0xb000 }, + [GCC_NPU_BWMON_BCR] = { 0x73000 }, + [GCC_NPU_BCR] = { 0x4d000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 }, + [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 }, + [GCC_PCIE_1_BCR] = { 0x8d000 }, + [GCC_PCIE_1_LINK_DOWN_BCR] = { 0x8e014 }, + [GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x8e020 }, + [GCC_PCIE_1_PHY_BCR] = { 0x8e01c }, + [GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x8e000 }, + [GCC_PCIE_2_BCR] = { 0x6000 }, + [GCC_PCIE_2_LINK_DOWN_BCR] = { 0x1f014 }, + [GCC_PCIE_2_NOCSR_COM_PHY_BCR] = { 0x1f020 }, + [GCC_PCIE_2_PHY_BCR] = { 0x1f01c }, + [GCC_PCIE_2_PHY_NOCSR_COM_PHY_BCR] = { 0x1f028 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_PRNG_BCR] = { 0x34000 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_TSIF_BCR] = { 0x36000 }, + [GCC_UFS_CARD_BCR] = { 0x75000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB30_SEC_BCR] = { 0x10000 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, + [GCC_VIDEO_AXI0_CLK_ARES] = { 0xb024, 2 }, + [GCC_VIDEO_AXI1_CLK_ARES] = { 0xb028, 2 }, +}; + +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s5_clk_src), +}; + +static const struct regmap_config gcc_sm8250_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9c100, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sm8250_desc = { + .config = &gcc_sm8250_regmap_config, + .clks = gcc_sm8250_clocks, + .num_clks = ARRAY_SIZE(gcc_sm8250_clocks), + .resets = gcc_sm8250_resets, + .num_resets = ARRAY_SIZE(gcc_sm8250_resets), + .gdscs = gcc_sm8250_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sm8250_gdscs), +}; + +static const struct of_device_id gcc_sm8250_match_table[] = { + { .compatible = "qcom,gcc-sm8250" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sm8250_match_table); + +static int gcc_sm8250_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_sm8250_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Disable the GPLL0 active input to NPU and GPU + * via MISC registers. + */ + regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); + regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + + /* + * Keep the clocks always-ON + * GCC_VIDEO_AHB_CLK, GCC_CAMERA_AHB_CLK, GCC_DISP_AHB_CLK, + * GCC_CPUSS_DVM_BUS_CLK, GCC_GPU_CFG_AHB_CLK, + * GCC_SYS_NOC_CPUSS_AHB_CLK + */ + regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x4818c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x52000, BIT(0), BIT(0)); + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + return qcom_cc_really_probe(pdev, &gcc_sm8250_desc, regmap); +} + +static struct platform_driver gcc_sm8250_driver = { + .probe = gcc_sm8250_probe, + .driver = { + .name = "gcc-sm8250", + .of_match_table = gcc_sm8250_match_table, + }, +}; + +static int __init gcc_sm8250_init(void) +{ + return platform_driver_register(&gcc_sm8250_driver); +} +subsys_initcall(gcc_sm8250_init); + +static void __exit gcc_sm8250_exit(void) +{ + platform_driver_unregister(&gcc_sm8250_driver); +} +module_exit(gcc_sm8250_exit); + +MODULE_DESCRIPTION("QTI GCC SM8250 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c index a96c0b945de2..7b656b6aeced 100644 --- a/drivers/clk/qcom/gpucc-sc7180.c +++ b/drivers/clk/qcom/gpucc-sc7180.c @@ -170,8 +170,45 @@ static struct gdsc cx_gdsc = { .flags = VOTABLE, }; +/* + * On SC7180 the GPU GX domain is *almost* entirely controlled by the GMU + * running in the CX domain so the CPU doesn't need to know anything about the + * GX domain EXCEPT.... + * + * Hardware constraints dictate that the GX be powered down before the CX. If + * the GMU crashes it could leave the GX on. In order to successfully bring back + * the device the CPU needs to disable the GX headswitch. There being no sane + * way to reach in and touch that register from deep inside the GPU driver we + * need to set up the infrastructure to be able to ensure that the GPU can + * ensure that the GX is off during this super special case. We do this by + * defining a GX gdsc with a dummy enable function and a "default" disable + * function. + * + * This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU + * driver. During power up, nothing will happen from the CPU (and the GMU will + * power up normally but during power down this will ensure that the GX domain + * is *really* off - this gives us a semi standard way of doing what we need. + */ +static int gx_gdsc_enable(struct generic_pm_domain *domain) +{ + /* Do nothing but give genpd the impression that we were successful */ + return 0; +} + +static struct gdsc gx_gdsc = { + .gdscr = 0x100c, + .clamp_io_ctrl = 0x1508, + .pd = { + .name = "gx_gdsc", + .power_on = gx_gdsc_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO, +}; + static struct gdsc *gpu_cc_sc7180_gdscs[] = { [CX_GDSC] = &cx_gdsc, + [GX_GDSC] = &gx_gdsc, }; static struct clk_regmap *gpu_cc_sc7180_clocks[] = { diff --git a/drivers/clk/qcom/mss-sc7180.c b/drivers/clk/qcom/mss-sc7180.c new file mode 100644 index 000000000000..673fa1a4f734 --- /dev/null +++ b/drivers/clk/qcom/mss-sc7180.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/pm_clock.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,mss-sc7180.h> + +#include "clk-regmap.h" +#include "clk-branch.h" +#include "common.h" + +static struct clk_branch mss_axi_nav_clk = { + .halt_reg = 0x20bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mss_axi_nav_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "gcc_mss_nav_axi", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mss_axi_crypto_clk = { + .halt_reg = 0x20cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20cc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mss_axi_crypto_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "gcc_mss_mfab_axis", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct regmap_config mss_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, + .max_register = 0x41aa0cc, +}; + +static struct clk_regmap *mss_sc7180_clocks[] = { + [MSS_AXI_CRYPTO_CLK] = &mss_axi_crypto_clk.clkr, + [MSS_AXI_NAV_CLK] = &mss_axi_nav_clk.clkr, +}; + +static const struct qcom_cc_desc mss_sc7180_desc = { + .config = &mss_regmap_config, + .clks = mss_sc7180_clocks, + .num_clks = ARRAY_SIZE(mss_sc7180_clocks), +}; + +static int mss_sc7180_probe(struct platform_device *pdev) +{ + int ret; + + pm_runtime_enable(&pdev->dev); + ret = pm_clk_create(&pdev->dev); + if (ret) + goto disable_pm_runtime; + + ret = pm_clk_add(&pdev->dev, "cfg_ahb"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + goto destroy_pm_clk; + } + + ret = qcom_cc_probe(pdev, &mss_sc7180_desc); + if (ret < 0) + goto destroy_pm_clk; + + return 0; + +destroy_pm_clk: + pm_clk_destroy(&pdev->dev); + +disable_pm_runtime: + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int mss_sc7180_remove(struct platform_device *pdev) +{ + pm_clk_destroy(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static const struct dev_pm_ops mss_sc7180_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static const struct of_device_id mss_sc7180_match_table[] = { + { .compatible = "qcom,sc7180-mss" }, + { } +}; +MODULE_DEVICE_TABLE(of, mss_sc7180_match_table); + +static struct platform_driver mss_sc7180_driver = { + .probe = mss_sc7180_probe, + .remove = mss_sc7180_remove, + .driver = { + .name = "sc7180-mss", + .of_match_table = mss_sc7180_match_table, + .pm = &mss_sc7180_pm_ops, + }, +}; + +static int __init mss_sc7180_init(void) +{ + return platform_driver_register(&mss_sc7180_driver); +} +subsys_initcall(mss_sc7180_init); + +static void __exit mss_sc7180_exit(void) +{ + platform_driver_unregister(&mss_sc7180_driver); +} +module_exit(mss_sc7180_exit); + +MODULE_DESCRIPTION("QTI MSS SC7180 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 250d8165167a..ac2dd92ce2ef 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -20,7 +20,7 @@ config CLK_RENESAS select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793 select CLK_R8A7792 if ARCH_R8A7792 select CLK_R8A7794 if ARCH_R8A7794 - select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 || ARCH_R8A7795 + select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 select CLK_R8A77960 if ARCH_R8A77960 select CLK_R8A77961 if ARCH_R8A77961 select CLK_R8A77965 if ARCH_R8A77965 @@ -161,6 +161,7 @@ config CLK_RCAR_GEN3_CPG config CLK_RCAR_USB2_CLOCK_SEL bool "Renesas R-Car USB2 clock selector support" depends on ARCH_RENESAS || COMPILE_TEST + select RESET_CONTROLLER help This is a driver for R-Car USB2 clock selector diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index fbc8c75f4314..ff5b3020cb03 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -44,6 +44,7 @@ enum clk_ids { CLK_S3, CLK_SDSRC, CLK_SSPSRC, + CLK_RPCSRC, CLK_RINT, /* Module Clocks */ @@ -70,6 +71,12 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1), + + DEF_BASE("rpc", R8A7795_CLK_RPC, CLK_TYPE_GEN3_RPC, + CLK_RPCSRC), + DEF_BASE("rpcd2", R8A7795_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, + R8A7795_CLK_RPC), DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), @@ -242,6 +249,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("can-fd", 914, R8A7795_CLK_S3D2), DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4), DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), + DEF_MOD("rpc-if", 917, R8A7795_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A7795_CLK_S0D6), DEF_MOD("i2c5", 919, R8A7795_CLK_S0D6), DEF_MOD("i2c-dvfs", 926, R8A7795_CLK_CP), diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index e8420d3ada94..e8d466dbc7f9 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -46,6 +46,7 @@ enum clk_ids { CLK_S3, CLK_SDSRC, CLK_SSPSRC, + CLK_RPCSRC, CLK_RINT, /* Module Clocks */ @@ -72,6 +73,12 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1), + + DEF_BASE("rpc", R8A7796_CLK_RPC, CLK_TYPE_GEN3_RPC, + CLK_RPCSRC), + DEF_BASE("rpcd2", R8A7796_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, + R8A7796_CLK_RPC), DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), @@ -105,6 +112,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cr", R8A7796_CLK_CR, CLK_PLL1_DIV4, 2, 1), DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("cpex", R8A7796_CLK_CPEX, CLK_EXTAL, 2, 1), @@ -132,6 +140,7 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = { DEF_MOD("sys-dmac2", 217, R8A7796_CLK_S3D1), DEF_MOD("sys-dmac1", 218, R8A7796_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A7796_CLK_S0D3), + DEF_MOD("sceg-pub", 229, R8A7796_CLK_CR), DEF_MOD("cmt3", 300, R8A7796_CLK_R), DEF_MOD("cmt2", 301, R8A7796_CLK_R), DEF_MOD("cmt1", 302, R8A7796_CLK_R), @@ -215,6 +224,7 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = { DEF_MOD("can-fd", 914, R8A7796_CLK_S3D2), DEF_MOD("can-if1", 915, R8A7796_CLK_S3D4), DEF_MOD("can-if0", 916, R8A7796_CLK_S3D4), + DEF_MOD("rpc-if", 917, R8A7796_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A7796_CLK_S0D6), DEF_MOD("i2c5", 919, R8A7796_CLK_S0D6), DEF_MOD("i2c-dvfs", 926, R8A7796_CLK_CP), diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index b3af4da2ca74..7a05a2fc1cc6 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -43,6 +43,7 @@ enum clk_ids { CLK_S3, CLK_SDSRC, CLK_SSPSRC, + CLK_RPCSRC, CLK_RINT, /* Module Clocks */ @@ -68,6 +69,12 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1), + + DEF_BASE("rpc", R8A77965_CLK_RPC, CLK_TYPE_GEN3_RPC, + CLK_RPCSRC), + DEF_BASE("rpcd2", R8A77965_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, + R8A77965_CLK_RPC), DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), @@ -99,7 +106,8 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, CLK_SDSRC, 0x268), DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, CLK_SDSRC, 0x26c), - DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cr", R8A77965_CLK_CR, CLK_PLL1_DIV4, 2, 1), DEF_FIXED("cp", R8A77965_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("cpex", R8A77965_CLK_CPEX, CLK_EXTAL, 2, 1), @@ -127,6 +135,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("sys-dmac2", 217, R8A77965_CLK_S3D1), DEF_MOD("sys-dmac1", 218, R8A77965_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A77965_CLK_S0D3), + DEF_MOD("sceg-pub", 229, R8A77965_CLK_CR), DEF_MOD("cmt3", 300, R8A77965_CLK_R), DEF_MOD("cmt2", 301, R8A77965_CLK_R), @@ -215,6 +224,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("can-fd", 914, R8A77965_CLK_S3D2), DEF_MOD("can-if1", 915, R8A77965_CLK_S3D4), DEF_MOD("can-if0", 916, R8A77965_CLK_S3D4), + DEF_MOD("rpc-if", 917, R8A77965_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A77965_CLK_S0D6), DEF_MOD("i2c5", 919, R8A77965_CLK_S0D6), DEF_MOD("i2c-dvfs", 926, R8A77965_CLK_CP), diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index ceabf55c21c2..8eda2e3e2480 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -105,6 +105,7 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = { DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, CLK_SDSRC, 0x026c), DEF_FIXED("cl", R8A77990_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cr", R8A77990_CLK_CR, CLK_PLL1D2, 2, 1), DEF_FIXED("cp", R8A77990_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("cpex", R8A77990_CLK_CPEX, CLK_EXTAL, 4, 1), @@ -135,6 +136,7 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = { DEF_MOD("sys-dmac2", 217, R8A77990_CLK_S3D1), DEF_MOD("sys-dmac1", 218, R8A77990_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A77990_CLK_S3D1), + DEF_MOD("sceg-pub", 229, R8A77990_CLK_CR), DEF_MOD("cmt3", 300, R8A77990_CLK_R), DEF_MOD("cmt2", 301, R8A77990_CLK_R), diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index 962bb337f2e7..056ebf3e70e2 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -91,6 +91,7 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_FIXED("s3d4", R8A77995_CLK_S3D4, CLK_S3, 4, 1), DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cr", R8A77995_CLK_CR, CLK_PLL1D2, 2, 1), DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("cpex", R8A77995_CLK_CPEX, CLK_EXTAL, 4, 1), @@ -122,6 +123,7 @@ static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = { DEF_MOD("sys-dmac2", 217, R8A77995_CLK_S3D1), DEF_MOD("sys-dmac1", 218, R8A77995_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A77995_CLK_S3D1), + DEF_MOD("sceg-pub", 229, R8A77995_CLK_CR), DEF_MOD("cmt3", 300, R8A77995_CLK_R), DEF_MOD("cmt2", 301, R8A77995_CLK_R), DEF_MOD("cmt1", 302, R8A77995_CLK_R), diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c index b97f5f9326cf..d4c02986c34e 100644 --- a/drivers/clk/renesas/rcar-usb2-clock-sel.c +++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c @@ -19,6 +19,7 @@ #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/slab.h> #define USB20_CLKSET0 0x00 @@ -26,9 +27,16 @@ #define CLKSET0_PRIVATE BIT(0) #define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE) +static const struct clk_bulk_data rcar_usb2_clocks[] = { + { .id = "ehci_ohci", }, + { .id = "hs-usb-if", }, +}; + struct usb2_clock_sel_priv { void __iomem *base; struct clk_hw hw; + struct clk_bulk_data clks[ARRAY_SIZE(rcar_usb2_clocks)]; + struct reset_control *rsts; bool extal; bool xtal; }; @@ -53,14 +61,32 @@ static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv) static int usb2_clock_sel_enable(struct clk_hw *hw) { - usb2_clock_sel_enable_extal_only(to_priv(hw)); + struct usb2_clock_sel_priv *priv = to_priv(hw); + int ret; + + ret = reset_control_deassert(priv->rsts); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clks), priv->clks); + if (ret) { + reset_control_assert(priv->rsts); + return ret; + } + + usb2_clock_sel_enable_extal_only(priv); return 0; } static void usb2_clock_sel_disable(struct clk_hw *hw) { - usb2_clock_sel_disable_extal_only(to_priv(hw)); + struct usb2_clock_sel_priv *priv = to_priv(hw); + + usb2_clock_sel_disable_extal_only(priv); + + clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clks), priv->clks); + reset_control_assert(priv->rsts); } /* @@ -119,6 +145,7 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) struct usb2_clock_sel_priv *priv; struct clk *clk; struct clk_init_data init; + int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -128,6 +155,15 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + memcpy(priv->clks, rcar_usb2_clocks, sizeof(priv->clks)); + ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clks), priv->clks); + if (ret < 0) + return ret; + + priv->rsts = devm_reset_control_array_get(dev, true, false); + if (IS_ERR(priv->rsts)) + return PTR_ERR(priv->rsts); + pm_runtime_enable(dev); pm_runtime_get_sync(dev); diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 4abe7ff31f53..975454a3dd72 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -51,9 +51,9 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw) u16 degrees; u32 delay_num = 0; - /* See the comment for rockchip_mmc_set_phase below */ + /* Constant signal, no measurable phase shift */ if (!rate) - return -EINVAL; + return 0; raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index dad31308c071..1949ae7851b2 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -356,10 +356,6 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( } ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); - if (!ctx) { - panic("%s: unable to allocate ctx\n", __func__); - return ctx; - } if (cmu->pll_clks) samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index 54a464fa63e0..8be4722f6064 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -65,54 +65,49 @@ static const struct clk_ops dbgclk_ops = { .get_parent = socfpga_gate_get_parent, }; -struct clk *s10_register_gate(const char *name, const char *parent_name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *regbase, unsigned long gate_reg, - unsigned long gate_idx, unsigned long div_reg, - unsigned long div_offset, u8 div_width, - unsigned long bypass_reg, u8 bypass_shift, - u8 fixed_div) +struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase) { struct clk *clk; struct socfpga_gate_clk *socfpga_clk; struct clk_init_data init; + const char * const *parent_names = clks->parent_names; + const char *parent_name = clks->parent_name; socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); if (!socfpga_clk) return NULL; - socfpga_clk->hw.reg = regbase + gate_reg; - socfpga_clk->hw.bit_idx = gate_idx; + socfpga_clk->hw.reg = regbase + clks->gate_reg; + socfpga_clk->hw.bit_idx = clks->gate_idx; gateclk_ops.enable = clk_gate_ops.enable; gateclk_ops.disable = clk_gate_ops.disable; - socfpga_clk->fixed_div = fixed_div; + socfpga_clk->fixed_div = clks->fixed_div; - if (div_reg) - socfpga_clk->div_reg = regbase + div_reg; + if (clks->div_reg) + socfpga_clk->div_reg = regbase + clks->div_reg; else socfpga_clk->div_reg = NULL; - socfpga_clk->width = div_width; - socfpga_clk->shift = div_offset; + socfpga_clk->width = clks->div_width; + socfpga_clk->shift = clks->div_offset; - if (bypass_reg) - socfpga_clk->bypass_reg = regbase + bypass_reg; + if (clks->bypass_reg) + socfpga_clk->bypass_reg = regbase + clks->bypass_reg; else socfpga_clk->bypass_reg = NULL; - socfpga_clk->bypass_shift = bypass_shift; + socfpga_clk->bypass_shift = clks->bypass_shift; - if (streq(name, "cs_pdbg_clk")) + if (streq(clks->name, "cs_pdbg_clk")) init.ops = &dbgclk_ops; else init.ops = &gateclk_ops; - init.name = name; - init.flags = flags; + init.name = clks->name; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names ? parent_names : &parent_name; socfpga_clk->hw.hw.init = &init; @@ -121,6 +116,5 @@ struct clk *s10_register_gate(const char *name, const char *parent_name, kfree(socfpga_clk); return NULL; } - return clk; } diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index 1a191eeeebba..dd6d4056e9de 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -73,26 +73,27 @@ static const struct clk_ops peri_cnt_clk_ops = { .get_parent = clk_periclk_get_parent, }; -struct clk *s10_register_periph(const char *name, const char *parent_name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *reg, unsigned long offset) +struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks, + void __iomem *reg) { struct clk *clk; struct socfpga_periph_clk *periph_clk; struct clk_init_data init; + const char *name = clks->name; + const char *parent_name = clks->parent_name; + const char * const *parent_names = clks->parent_names; periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); if (WARN_ON(!periph_clk)) return NULL; - periph_clk->hw.reg = reg + offset; + periph_clk->hw.reg = reg + clks->offset; init.name = name; init.ops = &peri_c_clk_ops; - init.flags = flags; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names ? parent_names : &parent_name; periph_clk->hw.hw.init = &init; @@ -105,38 +106,37 @@ struct clk *s10_register_periph(const char *name, const char *parent_name, return clk; } -struct clk *s10_register_cnt_periph(const char *name, const char *parent_name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *regbase, unsigned long offset, - u8 fixed_divider, unsigned long bypass_reg, - unsigned long bypass_shift) +struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks, + void __iomem *regbase) { struct clk *clk; struct socfpga_periph_clk *periph_clk; struct clk_init_data init; + const char *name = clks->name; + const char *parent_name = clks->parent_name; + const char * const *parent_names = clks->parent_names; periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); if (WARN_ON(!periph_clk)) return NULL; - if (offset) - periph_clk->hw.reg = regbase + offset; + if (clks->offset) + periph_clk->hw.reg = regbase + clks->offset; else periph_clk->hw.reg = NULL; - if (bypass_reg) - periph_clk->bypass_reg = regbase + bypass_reg; + if (clks->bypass_reg) + periph_clk->bypass_reg = regbase + clks->bypass_reg; else periph_clk->bypass_reg = NULL; - periph_clk->bypass_shift = bypass_shift; - periph_clk->fixed_div = fixed_divider; + periph_clk->bypass_shift = clks->bypass_shift; + periph_clk->fixed_div = clks->fixed_divider; init.name = name; init.ops = &peri_cnt_clk_ops; - init.flags = flags; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names ? parent_names : &parent_name; periph_clk->hw.hw.init = &init; diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index 4705eb544f01..a301bb22f36c 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -39,7 +39,9 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, /* read VCO1 reg for numerator and denominator */ reg = readl(socfpgaclk->hw.reg); refdiv = (reg & SOCFPGA_PLL_REFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT; - vco_freq = (unsigned long long)parent_rate / refdiv; + + vco_freq = parent_rate; + do_div(vco_freq, refdiv); /* Read mdiv and fdiv from the fdbck register */ reg = readl(socfpgaclk->hw.reg + 0x4); @@ -108,19 +110,20 @@ static struct clk_ops clk_boot_ops = { .prepare = clk_pll_prepare, }; -struct clk *s10_register_pll(const char *name, const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *reg, unsigned long offset) +struct clk *s10_register_pll(const struct stratix10_pll_clock *clks, + void __iomem *reg) { struct clk *clk; struct socfpga_pll *pll_clk; struct clk_init_data init; + const char *name = clks->name; + const char * const *parent_names = clks->parent_names; pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); if (WARN_ON(!pll_clk)) return NULL; - pll_clk->hw.reg = reg + offset; + pll_clk->hw.reg = reg + clks->offset; if (streq(name, SOCFPGA_BOOT_CLK)) init.ops = &clk_boot_ops; @@ -128,9 +131,9 @@ struct clk *s10_register_pll(const char *name, const char * const *parent_names, init.ops = &clk_pll_ops; init.name = name; - init.flags = flags; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names; pll_clk->hw.hw.init = &init; diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index 993f3a73c71e..dea7c6c7d269 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c @@ -177,9 +177,7 @@ static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, int i; for (i = 0; i < nums; i++) { - clk = s10_register_periph(clks[i].name, clks[i].parent_name, - clks[i].parent_names, clks[i].num_parents, - clks[i].flags, base, clks[i].offset); + clk = s10_register_periph(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); @@ -198,14 +196,7 @@ static int s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *cl int i; for (i = 0; i < nums; i++) { - clk = s10_register_cnt_periph(clks[i].name, clks[i].parent_name, - clks[i].parent_names, - clks[i].num_parents, - clks[i].flags, base, - clks[i].offset, - clks[i].fixed_divider, - clks[i].bypass_reg, - clks[i].bypass_shift); + clk = s10_register_cnt_periph(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); @@ -225,16 +216,7 @@ static int s10_clk_register_gate(const struct stratix10_gate_clock *clks, int i; for (i = 0; i < nums; i++) { - clk = s10_register_gate(clks[i].name, clks[i].parent_name, - clks[i].parent_names, - clks[i].num_parents, - clks[i].flags, base, - clks[i].gate_reg, - clks[i].gate_idx, clks[i].div_reg, - clks[i].div_offset, clks[i].div_width, - clks[i].bypass_reg, - clks[i].bypass_shift, - clks[i].fixed_div); + clk = s10_register_gate(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); @@ -254,10 +236,7 @@ static int s10_clk_register_pll(const struct stratix10_pll_clock *clks, int i; for (i = 0; i < nums; i++) { - clk = s10_register_pll(clks[i].name, clks[i].parent_names, - clks[i].num_parents, - clks[i].flags, base, - clks[i].offset); + clk = s10_register_pll(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h index e8e121907952..fcabef42249c 100644 --- a/drivers/clk/socfpga/stratix10-clk.h +++ b/drivers/clk/socfpga/stratix10-clk.h @@ -60,21 +60,12 @@ struct stratix10_gate_clock { u8 fixed_div; }; -struct clk *s10_register_pll(const char *, const char *const *, u8, - unsigned long, void __iomem *, unsigned long); - -struct clk *s10_register_periph(const char *, const char *, - const char * const *, u8, unsigned long, - void __iomem *, unsigned long); -struct clk *s10_register_cnt_periph(const char *, const char *, - const char * const *, u8, - unsigned long, void __iomem *, - unsigned long, u8, unsigned long, - unsigned long); -struct clk *s10_register_gate(const char *, const char *, - const char * const *, u8, - unsigned long, void __iomem *, - unsigned long, unsigned long, - unsigned long, unsigned long, u8, - unsigned long, u8, u8); +struct clk *s10_register_pll(const struct stratix10_pll_clock *, + void __iomem *); +struct clk *s10_register_periph(const struct stratix10_perip_c_clock *, + void __iomem *); +struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *, + void __iomem *); +struct clk *s10_register_gate(const struct stratix10_gate_clock *, + void __iomem *); #endif /* __STRATIX10_CLK_H */ diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig index 3c219af25100..e18c80fbe804 100644 --- a/drivers/clk/sprd/Kconfig +++ b/drivers/clk/sprd/Kconfig @@ -13,4 +13,12 @@ config SPRD_SC9860_CLK tristate "Support for the Spreadtrum SC9860 clocks" depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST default ARM64 && ARCH_SPRD + +config SPRD_SC9863A_CLK + tristate "Support for the Spreadtrum SC9863A clocks" + depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST + default ARM64 && ARCH_SPRD + help + Support for the global clock controller on sc9863a devices. + Say Y if you want to use peripheral devices on sc9863a SoC. endif diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile index d4c00788d53c..41d90e0d7863 100644 --- a/drivers/clk/sprd/Makefile +++ b/drivers/clk/sprd/Makefile @@ -10,3 +10,4 @@ clk-sprd-y += pll.o ## SoC support obj-$(CONFIG_SPRD_SC9860_CLK) += sc9860-clk.o +obj-$(CONFIG_SPRD_SC9863A_CLK) += sc9863a-clk.o diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c index c0af4779892b..d620bbbcdfc8 100644 --- a/drivers/clk/sprd/common.c +++ b/drivers/clk/sprd/common.c @@ -40,7 +40,8 @@ int sprd_clk_regmap_init(struct platform_device *pdev, const struct sprd_clk_desc *desc) { void __iomem *base; - struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; struct regmap *regmap; if (of_find_property(node, "sprd,syscon", NULL)) { @@ -49,6 +50,13 @@ int sprd_clk_regmap_init(struct platform_device *pdev, pr_err("%s: failed to get syscon regmap\n", __func__); return PTR_ERR(regmap); } + } else if (of_device_is_compatible(of_get_parent(dev->of_node), + "syscon")) { + regmap = device_node_to_regmap(of_get_parent(dev->of_node)); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap from its parent.\n"); + return PTR_ERR(regmap); + } } else { base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) diff --git a/drivers/clk/sprd/composite.h b/drivers/clk/sprd/composite.h index 04ab3f587ee2..adbabbe596b7 100644 --- a/drivers/clk/sprd/composite.h +++ b/drivers/clk/sprd/composite.h @@ -18,26 +18,43 @@ struct sprd_comp { struct sprd_clk_common common; }; -#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \ - _mshift, _mwidth, _dshift, _dwidth, _flags) \ +#define SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, _dwidth, \ + _flags, _fn) \ struct sprd_comp _struct = { \ .mux = _SPRD_MUX_CLK(_mshift, _mwidth, _table), \ .div = _SPRD_DIV_CLK(_dshift, _dwidth), \ .common = { \ .regmap = NULL, \ .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS(_name, \ - _parent, \ - &sprd_comp_ops, \ - _flags), \ + .hw.init = _fn(_name, _parent, \ + &sprd_comp_ops, _flags), \ } \ } -#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift, \ - _mwidth, _dshift, _dwidth, _flags) \ - SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, \ - NULL, _mshift, _mwidth, \ - _dshift, _dwidth, _flags) +#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, _dwidth, _flags) \ + SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, _dwidth, \ + _flags, CLK_HW_INIT_PARENTS) + +#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift, \ + _mwidth, _dshift, _dwidth, _flags) \ + SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, NULL, \ + _mshift, _mwidth, _dshift, _dwidth, _flags) + +#define SPRD_COMP_CLK_DATA_TABLE(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, \ + _dwidth, _flags) \ + SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, _dwidth, \ + _flags, CLK_HW_INIT_PARENTS_DATA) + +#define SPRD_COMP_CLK_DATA(_struct, _name, _parent, _reg, _mshift, \ + _mwidth, _dshift, _dwidth, _flags) \ + SPRD_COMP_CLK_DATA_TABLE(_struct, _name, _parent, _reg, NULL, \ + _mshift, _mwidth, _dshift, _dwidth, \ + _flags) static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw) { diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h index 87510e3d0e14..6acfe6b179fc 100644 --- a/drivers/clk/sprd/div.h +++ b/drivers/clk/sprd/div.h @@ -35,20 +35,28 @@ struct sprd_div { struct sprd_clk_common common; }; -#define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \ - _shift, _width, _flags) \ +#define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _shift, _width, _flags, _fn) \ struct sprd_div _struct = { \ .div = _SPRD_DIV_CLK(_shift, _width), \ .common = { \ .regmap = NULL, \ .reg = _reg, \ - .hw.init = CLK_HW_INIT(_name, \ - _parent, \ - &sprd_div_ops, \ - _flags), \ + .hw.init = _fn(_name, _parent, \ + &sprd_div_ops, _flags), \ } \ } +#define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _shift, _width, _flags, CLK_HW_INIT) + +#define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _shift, _width, _flags, CLK_HW_INIT_HW) + static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw) { struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c index f59d1936b412..574cfc116bbc 100644 --- a/drivers/clk/sprd/gate.c +++ b/drivers/clk/sprd/gate.c @@ -79,6 +79,17 @@ static int sprd_sc_gate_enable(struct clk_hw *hw) return 0; } + +static int sprd_pll_sc_gate_prepare(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_sc_gate_toggle(sg, true); + udelay(sg->udelay); + + return 0; +} + static int sprd_gate_is_enabled(struct clk_hw *hw) { struct sprd_gate *sg = hw_to_sprd_gate(hw); @@ -109,3 +120,9 @@ const struct clk_ops sprd_sc_gate_ops = { }; EXPORT_SYMBOL_GPL(sprd_sc_gate_ops); +const struct clk_ops sprd_pll_sc_gate_ops = { + .unprepare = sprd_sc_gate_disable, + .prepare = sprd_pll_sc_gate_prepare, + .is_enabled = sprd_gate_is_enabled, +}; +EXPORT_SYMBOL_GPL(sprd_pll_sc_gate_ops); diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h index dc352ea55e1f..b55817869367 100644 --- a/drivers/clk/sprd/gate.h +++ b/drivers/clk/sprd/gate.h @@ -14,37 +14,136 @@ struct sprd_gate { u32 enable_mask; u16 flags; u16 sc_offset; + u16 udelay; struct sprd_clk_common common; }; -#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ - _enable_mask, _flags, _gate_flags, _ops) \ +#define SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, _fn) \ struct sprd_gate _struct = { \ .enable_mask = _enable_mask, \ .sc_offset = _sc_offset, \ .flags = _gate_flags, \ + .udelay = _udelay, \ .common = { \ .regmap = NULL, \ .reg = _reg, \ - .hw.init = CLK_HW_INIT(_name, \ - _parent, \ - _ops, \ - _flags), \ + .hw.init = _fn(_name, _parent, \ + _ops, _flags), \ } \ } +#define SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops) \ + SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, CLK_HW_INIT) + +#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, 0, _ops) + +#define SPRD_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_sc_gate_ops) + #define SPRD_GATE_CLK(_struct, _name, _parent, _reg, \ _enable_mask, _flags, _gate_flags) \ SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, 0, \ _enable_mask, _flags, _gate_flags, \ &sprd_gate_ops) -#define SPRD_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ - _enable_mask, _flags, _gate_flags) \ - SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ +#define SPRD_PLL_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ _enable_mask, _flags, _gate_flags, \ - &sprd_sc_gate_ops) + _udelay) \ + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) + + +#define SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, \ + _flags, _gate_flags, \ + _udelay, _ops) \ + SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, \ + CLK_HW_INIT_HW) + +#define SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, \ + _flags, _gate_flags, 0, _ops) + +#define SPRD_SC_GATE_CLK_HW(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags) \ + SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, &sprd_sc_gate_ops) + +#define SPRD_GATE_CLK_HW(_struct, _name, _parent, _reg, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, 0, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_gate_ops) + +#define SPRD_PLL_SC_GATE_CLK_HW(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay) \ + SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, \ + _flags, _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) + +#define SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent, \ + _reg, _sc_offset, \ + _enable_mask, _flags, \ + _gate_flags, _udelay, _ops) \ + SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, \ + CLK_HW_INIT_FW_NAME) + +#define SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent, \ + _reg, _sc_offset, \ + _enable_mask, _flags, \ + _gate_flags, 0, _ops) + +#define SPRD_SC_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, &sprd_sc_gate_ops) + +#define SPRD_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, 0, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_gate_ops) + +#define SPRD_PLL_SC_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent, \ + _reg, _sc_offset, \ + _enable_mask, _flags, \ + _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw) { @@ -55,5 +154,6 @@ static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw) extern const struct clk_ops sprd_gate_ops; extern const struct clk_ops sprd_sc_gate_ops; +extern const struct clk_ops sprd_pll_sc_gate_ops; #endif /* _SPRD_GATE_H_ */ diff --git a/drivers/clk/sprd/mux.h b/drivers/clk/sprd/mux.h index 892e4191cc7f..f3cc31dae06f 100644 --- a/drivers/clk/sprd/mux.h +++ b/drivers/clk/sprd/mux.h @@ -36,26 +36,40 @@ struct sprd_mux { .table = _table, \ } -#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table, \ - _reg, _shift, _width, \ - _flags) \ +#define SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags, _fn) \ struct sprd_mux _struct = { \ .mux = _SPRD_MUX_CLK(_shift, _width, _table), \ .common = { \ .regmap = NULL, \ .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS(_name, \ - _parents, \ - &sprd_mux_ops, \ - _flags), \ + .hw.init = _fn(_name, _parents, \ + &sprd_mux_ops, _flags), \ } \ } +#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags) \ + SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags, \ + CLK_HW_INIT_PARENTS) + #define SPRD_MUX_CLK(_struct, _name, _parents, _reg, \ _shift, _width, _flags) \ SPRD_MUX_CLK_TABLE(_struct, _name, _parents, NULL, \ _reg, _shift, _width, _flags) +#define SPRD_MUX_CLK_DATA_TABLE(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags) \ + SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags, \ + CLK_HW_INIT_PARENTS_DATA) + +#define SPRD_MUX_CLK_DATA(_struct, _name, _parents, _reg, \ + _shift, _width, _flags) \ + SPRD_MUX_CLK_DATA_TABLE(_struct, _name, _parents, NULL, \ + _reg, _shift, _width, _flags) + static inline struct sprd_mux *hw_to_sprd_mux(const struct clk_hw *hw) { struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c index 640270f51aa5..15791484388f 100644 --- a/drivers/clk/sprd/pll.c +++ b/drivers/clk/sprd/pll.c @@ -87,11 +87,12 @@ static u32 pll_get_ibias(u64 rate, const u64 *table) { u32 i, num = table[0]; - for (i = 1; i < num + 1; i++) - if (rate <= table[i]) + /* table[0] indicates the number of items in this table */ + for (i = 0; i < num; i++) + if (rate <= table[i + 1]) break; - return (i == num + 1) ? num : i; + return i == num ? num - 1 : i; } static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll, diff --git a/drivers/clk/sprd/pll.h b/drivers/clk/sprd/pll.h index e95f11e91ffe..6558f50d0296 100644 --- a/drivers/clk/sprd/pll.h +++ b/drivers/clk/sprd/pll.h @@ -61,27 +61,33 @@ struct sprd_pll { struct sprd_clk_common common; }; +#define SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, \ + _udelay, _k1, _k2, _fflag, \ + _fvco, _fn) \ + struct sprd_pll _struct = { \ + .regs_num = _regs_num, \ + .itable = _itable, \ + .factors = _factors, \ + .udelay = _udelay, \ + .k1 = _k1, \ + .k2 = _k2, \ + .fflag = _fflag, \ + .fvco = _fvco, \ + .common = { \ + .regmap = NULL, \ + .reg = _reg, \ + .hw.init = _fn(_name, _parent, \ + &sprd_pll_ops, 0),\ + }, \ + } + #define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ _regs_num, _itable, _factors, \ _udelay, _k1, _k2, _fflag, _fvco) \ - struct sprd_pll _struct = { \ - .regs_num = _regs_num, \ - .itable = _itable, \ - .factors = _factors, \ - .udelay = _udelay, \ - .k1 = _k1, \ - .k2 = _k2, \ - .fflag = _fflag, \ - .fvco = _fvco, \ - .common = { \ - .regmap = NULL, \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT(_name, \ - _parent, \ - &sprd_pll_ops, \ - 0), \ - }, \ - } + SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco, CLK_HW_INIT) #define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg, \ _regs_num, _itable, _factors, \ @@ -96,6 +102,19 @@ struct sprd_pll { _regs_num, _itable, _factors, \ _udelay, 1000, 1000, 0, 0) +#define SPRD_PLL_FW_NAME(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco) \ + SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco, CLK_HW_INIT_FW_NAME) + +#define SPRD_PLL_HW(_struct, _name, _parent, _reg, _regs_num, _itable, \ + _factors, _udelay, _k1, _k2, _fflag, _fvco) \ + SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco, CLK_HW_INIT_HW) + static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw) { struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); diff --git a/drivers/clk/sprd/sc9863a-clk.c b/drivers/clk/sprd/sc9863a-clk.c new file mode 100644 index 000000000000..a0631f7756cf --- /dev/null +++ b/drivers/clk/sprd/sc9863a-clk.c @@ -0,0 +1,1772 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Unisoc SC9863A clock driver + * + * Copyright (C) 2019 Unisoc, Inc. + * Author: Chunyan Zhang <chunyan.zhang@unisoc.com> + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/sprd,sc9863a-clk.h> + +#include "common.h" +#include "composite.h" +#include "div.h" +#include "gate.h" +#include "mux.h" +#include "pll.h" + +/* mpll*_gate clocks control cpu cores, they were enabled by default */ +SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98, + 0x1000, BIT(0), 0, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0x9c, + 0x1000, BIT(0), 0, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8, + 0x1000, BIT(0), 0, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc, + 0x1000, BIT(0), 0, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", 0x1e8, + 0x1000, BIT(0), 0, 0, 240); + +static struct sprd_clk_common *sc9863a_pmu_gate_clks[] = { + /* address base is 0x402b0000 */ + &mpll0_gate.common, + &dpll0_gate.common, + &lpll_gate.common, + &gpll_gate.common, + &dpll1_gate.common, + &mpll1_gate.common, + &mpll2_gate.common, + &isppll_gate.common, +}; + +static struct clk_hw_onecell_data sc9863a_pmu_gate_hws = { + .hws = { + [CLK_MPLL0_GATE] = &mpll0_gate.common.hw, + [CLK_DPLL0_GATE] = &dpll0_gate.common.hw, + [CLK_LPLL_GATE] = &lpll_gate.common.hw, + [CLK_GPLL_GATE] = &gpll_gate.common.hw, + [CLK_DPLL1_GATE] = &dpll1_gate.common.hw, + [CLK_MPLL1_GATE] = &mpll1_gate.common.hw, + [CLK_MPLL2_GATE] = &mpll2_gate.common.hw, + [CLK_ISPPLL_GATE] = &isppll_gate.common.hw, + }, + .num = CLK_PMU_APB_NUM, +}; + +static const struct sprd_clk_desc sc9863a_pmu_gate_desc = { + .clk_clks = sc9863a_pmu_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_pmu_gate_clks), + .hw_clks = &sc9863a_pmu_gate_hws, +}; + +static const u64 itable[5] = {4, 1000000000, 1200000000, + 1400000000, 1600000000}; + +static const struct clk_bit_field f_twpll[PLL_FACT_MAX] = { + { .shift = 95, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 1, .width = 1 }, /* mod_en */ + { .shift = 2, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 3, .width = 3 }, /* ibias */ + { .shift = 8, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_FW_NAME(twpll, "twpll", "ext-26m", 0x4, 3, itable, + f_twpll, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(twpll_768m, "twpll-768m", &twpll.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_384m, "twpll-384m", &twpll.common.hw, 4, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_192m, "twpll-192m", &twpll.common.hw, 8, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_96m, "twpll-96m", &twpll.common.hw, 16, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_48m, "twpll-48m", &twpll.common.hw, 32, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_24m, "twpll-24m", &twpll.common.hw, 64, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_12m, "twpll-12m", &twpll.common.hw, 128, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_512m, "twpll-512m", &twpll.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_256m, "twpll-256m", &twpll.common.hw, 6, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_128m, "twpll-128m", &twpll.common.hw, 12, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_64m, "twpll-64m", &twpll.common.hw, 24, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_307m2, "twpll-307m2", &twpll.common.hw, 5, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_219m4, "twpll-219m4", &twpll.common.hw, 7, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_170m6, "twpll-170m6", &twpll.common.hw, 9, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_153m6, "twpll-153m6", &twpll.common.hw, 10, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_76m8, "twpll-76m8", &twpll.common.hw, 20, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_51m2, "twpll-51m2", &twpll.common.hw, 30, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_38m4, "twpll-38m4", &twpll.common.hw, 40, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_19m2, "twpll-19m2", &twpll.common.hw, 80, 1, 0); + +static const struct clk_bit_field f_lpll[PLL_FACT_MAX] = { + { .shift = 95, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 1, .width = 1 }, /* mod_en */ + { .shift = 2, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 6, .width = 2 }, /* ibias */ + { .shift = 8, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_HW(lpll, "lpll", &lpll_gate.common.hw, 0x20, 3, itable, + f_lpll, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(lpll_409m6, "lpll-409m6", &lpll.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(lpll_245m76, "lpll-245m76", &lpll.common.hw, 5, 1, 0); + +static const struct clk_bit_field f_gpll[PLL_FACT_MAX] = { + { .shift = 95, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 1, .width = 1 }, /* mod_en */ + { .shift = 2, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 6, .width = 2 }, /* ibias */ + { .shift = 8, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 80, .width = 1 }, /* postdiv */ +}; +static SPRD_PLL_HW(gpll, "gpll", &gpll_gate.common.hw, 0x38, 3, itable, + f_gpll, 240, 1000, 1000, 1, 400000000); + +static SPRD_PLL_HW(isppll, "isppll", &isppll_gate.common.hw, 0x50, 3, itable, + f_gpll, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(isppll_468m, "isppll-468m", &isppll.common.hw, 2, 1, 0); + +static struct sprd_clk_common *sc9863a_pll_clks[] = { + /* address base is 0x40353000 */ + &twpll.common, + &lpll.common, + &gpll.common, + &isppll.common, +}; + +static struct clk_hw_onecell_data sc9863a_pll_hws = { + .hws = { + [CLK_TWPLL] = &twpll.common.hw, + [CLK_TWPLL_768M] = &twpll_768m.hw, + [CLK_TWPLL_384M] = &twpll_384m.hw, + [CLK_TWPLL_192M] = &twpll_192m.hw, + [CLK_TWPLL_96M] = &twpll_96m.hw, + [CLK_TWPLL_48M] = &twpll_48m.hw, + [CLK_TWPLL_24M] = &twpll_24m.hw, + [CLK_TWPLL_12M] = &twpll_12m.hw, + [CLK_TWPLL_512M] = &twpll_512m.hw, + [CLK_TWPLL_256M] = &twpll_256m.hw, + [CLK_TWPLL_128M] = &twpll_128m.hw, + [CLK_TWPLL_64M] = &twpll_64m.hw, + [CLK_TWPLL_307M2] = &twpll_307m2.hw, + [CLK_TWPLL_219M4] = &twpll_219m4.hw, + [CLK_TWPLL_170M6] = &twpll_170m6.hw, + [CLK_TWPLL_153M6] = &twpll_153m6.hw, + [CLK_TWPLL_76M8] = &twpll_76m8.hw, + [CLK_TWPLL_51M2] = &twpll_51m2.hw, + [CLK_TWPLL_38M4] = &twpll_38m4.hw, + [CLK_TWPLL_19M2] = &twpll_19m2.hw, + [CLK_LPLL] = &lpll.common.hw, + [CLK_LPLL_409M6] = &lpll_409m6.hw, + [CLK_LPLL_245M76] = &lpll_245m76.hw, + [CLK_GPLL] = &gpll.common.hw, + [CLK_ISPPLL] = &isppll.common.hw, + [CLK_ISPPLL_468M] = &isppll_468m.hw, + + }, + .num = CLK_ANLG_PHY_G1_NUM, +}; + +static const struct sprd_clk_desc sc9863a_pll_desc = { + .clk_clks = sc9863a_pll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_pll_clks), + .hw_clks = &sc9863a_pll_hws, +}; + +static const u64 itable_mpll[6] = {5, 1000000000, 1200000000, 1400000000, + 1600000000, 1800000000}; +static SPRD_PLL_HW(mpll0, "mpll0", &mpll0_gate.common.hw, 0x0, 3, itable_mpll, + f_gpll, 240, 1000, 1000, 1, 1000000000); +static SPRD_PLL_HW(mpll1, "mpll1", &mpll1_gate.common.hw, 0x18, 3, itable_mpll, + f_gpll, 240, 1000, 1000, 1, 1000000000); +static SPRD_PLL_HW(mpll2, "mpll2", &mpll2_gate.common.hw, 0x30, 3, itable_mpll, + f_gpll, 240, 1000, 1000, 1, 1000000000); +static CLK_FIXED_FACTOR_HW(mpll2_675m, "mpll2-675m", &mpll2.common.hw, 2, 1, 0); + +static struct sprd_clk_common *sc9863a_mpll_clks[] = { + /* address base is 0x40359000 */ + &mpll0.common, + &mpll1.common, + &mpll2.common, +}; + +static struct clk_hw_onecell_data sc9863a_mpll_hws = { + .hws = { + [CLK_MPLL0] = &mpll0.common.hw, + [CLK_MPLL1] = &mpll1.common.hw, + [CLK_MPLL2] = &mpll2.common.hw, + [CLK_MPLL2_675M] = &mpll2_675m.hw, + + }, + .num = CLK_ANLG_PHY_G4_NUM, +}; + +static const struct sprd_clk_desc sc9863a_mpll_desc = { + .clk_clks = sc9863a_mpll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_mpll_clks), + .hw_clks = &sc9863a_mpll_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(audio_gate, "audio-gate", "ext-26m", + 0x4, 0x1000, BIT(8), 0, 0); + +static SPRD_PLL_FW_NAME(rpll, "rpll", "ext-26m", 0x10, + 3, itable, f_lpll, 240, 1000, 1000, 0, 0); + +static CLK_FIXED_FACTOR_HW(rpll_390m, "rpll-390m", &rpll.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(rpll_260m, "rpll-260m", &rpll.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(rpll_195m, "rpll-195m", &rpll.common.hw, 4, 1, 0); +static CLK_FIXED_FACTOR_HW(rpll_26m, "rpll-26m", &rpll.common.hw, 30, 1, 0); + +static struct sprd_clk_common *sc9863a_rpll_clks[] = { + /* address base is 0x4035c000 */ + &audio_gate.common, + &rpll.common, +}; + +static struct clk_hw_onecell_data sc9863a_rpll_hws = { + .hws = { + [CLK_AUDIO_GATE] = &audio_gate.common.hw, + [CLK_RPLL] = &rpll.common.hw, + [CLK_RPLL_390M] = &rpll_390m.hw, + [CLK_RPLL_260M] = &rpll_260m.hw, + [CLK_RPLL_195M] = &rpll_195m.hw, + [CLK_RPLL_26M] = &rpll_26m.hw, + }, + .num = CLK_ANLG_PHY_G5_NUM, +}; + +static const struct sprd_clk_desc sc9863a_rpll_desc = { + .clk_clks = sc9863a_rpll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_rpll_clks), + .hw_clks = &sc9863a_rpll_hws, +}; + +static const u64 itable_dpll[5] = {4, 1211000000, 1320000000, 1570000000, + 1866000000}; +static SPRD_PLL_HW(dpll0, "dpll0", &dpll0_gate.common.hw, 0x0, 3, itable_dpll, + f_lpll, 240, 1000, 1000, 0, 0); +static SPRD_PLL_HW(dpll1, "dpll1", &dpll1_gate.common.hw, 0x18, 3, itable_dpll, + f_lpll, 240, 1000, 1000, 0, 0); + +static CLK_FIXED_FACTOR_HW(dpll0_933m, "dpll0-933m", &dpll0.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll0_622m3, "dpll0-622m3", &dpll0.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_400m, "dpll1-400m", &dpll0.common.hw, 4, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_266m7, "dpll1-266m7", &dpll0.common.hw, 6, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_123m1, "dpll1-123m1", &dpll0.common.hw, 13, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_50m, "dpll1-50m", &dpll0.common.hw, 32, 1, 0); + +static struct sprd_clk_common *sc9863a_dpll_clks[] = { + /* address base is 0x40363000 */ + &dpll0.common, + &dpll1.common, +}; + +static struct clk_hw_onecell_data sc9863a_dpll_hws = { + .hws = { + [CLK_DPLL0] = &dpll0.common.hw, + [CLK_DPLL1] = &dpll1.common.hw, + [CLK_DPLL0_933M] = &dpll0_933m.hw, + [CLK_DPLL0_622M3] = &dpll0_622m3.hw, + [CLK_DPLL0_400M] = &dpll1_400m.hw, + [CLK_DPLL0_266M7] = &dpll1_266m7.hw, + [CLK_DPLL0_123M1] = &dpll1_123m1.hw, + [CLK_DPLL0_50M] = &dpll1_50m.hw, + + }, + .num = CLK_ANLG_PHY_G7_NUM, +}; + +static const struct sprd_clk_desc sc9863a_dpll_desc = { + .clk_clks = sc9863a_dpll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_dpll_clks), + .hw_clks = &sc9863a_dpll_hws, +}; + +static CLK_FIXED_FACTOR_FW_NAME(clk_6m5, "clk-6m5", "ext-26m", 4, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_4m3, "clk-4m3", "ext-26m", 6, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_2m, "clk-2m", "ext-26m", 13, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_250k, "clk-250k", "ext-26m", 104, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_25m, "rco-25m", "rco-100m", 4, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_4m, "rco-4m", "rco-100m", 25, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_2m, "rco-2m", "rco-100m", 50, 1, 0); + +#define SC9863A_MUX_FLAG \ + (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT) + +static CLK_FIXED_FACTOR_FW_NAME(clk_13m, "clk-13m", "ext-26m", 2, 1, 0); +static const struct clk_parent_data emc_clk_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &twpll_768m.hw }, + { .hw = &twpll.common.hw }, +}; +static SPRD_MUX_CLK_DATA(emc_clk, "emc-clk", emc_clk_parents, 0x220, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aon_apb_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(aon_apb, "aon-apb", aon_apb_parents, 0x224, + 0, 3, 8, 2, 0); + +static const struct clk_parent_data adi_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_38m4.hw }, + { .hw = &twpll_51m2.hw }, +}; +static SPRD_MUX_CLK_DATA(adi_clk, "adi-clk", adi_parents, 0x228, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aux_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rpll_26m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_COMP_CLK_DATA(aux0_clk, "aux0-clk", aux_parents, 0x22c, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(aux1_clk, "aux1-clk", aux_parents, 0x230, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(aux2_clk, "aux2-clk", aux_parents, 0x234, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(probe_clk, "probe-clk", aux_parents, 0x238, + 0, 5, 8, 4, 0); + +static const struct clk_parent_data pwm_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rpll_26m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, +}; +static SPRD_MUX_CLK_DATA(pwm0_clk, "pwm0-clk", pwm_parents, 0x23c, + 0, 2, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm1_clk, "pwm1-clk", pwm_parents, 0x240, + 0, 2, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm2_clk, "pwm2-clk", pwm_parents, 0x244, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aon_thm_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &clk_250k.hw }, +}; +static SPRD_MUX_CLK_DATA(aon_thm_clk, "aon-thm-clk", aon_thm_parents, 0x25c, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data audif_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_38m4.hw }, + { .hw = &twpll_51m2.hw }, +}; +static SPRD_MUX_CLK_DATA(audif_clk, "audif-clk", audif_parents, 0x264, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data cpu_dap_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(cpu_dap_clk, "cpu-dap-clk", cpu_dap_parents, 0x26c, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data cpu_ts_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(cpu_ts_clk, "cpu-ts-clk", cpu_ts_parents, 0x274, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data djtag_tck_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(djtag_tck_clk, "djtag-tck-clk", djtag_tck_parents, 0x28c, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data emc_ref_parents[] = { + { .hw = &clk_6m5.hw }, + { .hw = &clk_13m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(emc_ref_clk, "emc-ref-clk", emc_ref_parents, 0x29c, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data cssys_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &mpll2_675m.hw }, +}; +static SPRD_COMP_CLK_DATA(cssys_clk, "cssys-clk", cssys_parents, 0x2a0, + 0, 4, 8, 2, 0); + +static const struct clk_parent_data aon_pmu_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rco_4m.hw }, + { .fw_name = "ext-4m" }, +}; +static SPRD_MUX_CLK_DATA(aon_pmu_clk, "aon-pmu-clk", aon_pmu_parents, 0x2a8, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data pmu_26m_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(pmu_26m_clk, "26m-pmu-clk", pmu_26m_parents, 0x2ac, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aon_tmr_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(aon_tmr_clk, "aon-tmr-clk", aon_tmr_parents, 0x2b0, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data power_cpu_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &rco_25m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(power_cpu_clk, "power-cpu-clk", power_cpu_parents, 0x2c4, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data ap_axi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_axi, "ap-axi", ap_axi_parents, 0x2c8, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data sdio_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &rpll_390m.hw }, + { .hw = &dpll1_400m.hw }, + { .hw = &lpll_409m6.hw }, +}; +static SPRD_MUX_CLK_DATA(sdio0_2x, "sdio0-2x", sdio_parents, 0x2cc, + 0, 3, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio1_2x, "sdio1-2x", sdio_parents, 0x2d4, + 0, 3, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio2_2x, "sdio2-2x", sdio_parents, 0x2dc, + 0, 3, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(emmc_2x, "emmc-2x", sdio_parents, 0x2e4, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data dpu_parents[] = { + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(dpu_clk, "dpu", dpu_parents, 0x2f4, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data dpu_dpi_parents[] = { + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_COMP_CLK_DATA(dpu_dpi, "dpu-dpi", dpu_dpi_parents, 0x2f8, + 0, 2, 8, 4, 0); + +static const struct clk_parent_data otg_ref_parents[] = { + { .hw = &twpll_12m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(otg_ref_clk, "otg-ref-clk", otg_ref_parents, 0x308, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data sdphy_apb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, +}; +static SPRD_MUX_CLK_DATA(sdphy_apb_clk, "sdphy-apb-clk", sdphy_apb_parents, 0x330, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data alg_io_apb_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_MUX_CLK_DATA(alg_io_apb_clk, "alg-io-apb-clk", alg_io_apb_parents, 0x33c, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data gpu_parents[] = { + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &gpll.common.hw }, +}; +static SPRD_COMP_CLK_DATA(gpu_core, "gpu-core", gpu_parents, 0x344, + 0, 3, 8, 2, 0); +static SPRD_COMP_CLK_DATA(gpu_soc, "gpu-soc", gpu_parents, 0x348, + 0, 3, 8, 2, 0); + +static const struct clk_parent_data mm_emc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_emc, "mm-emc", mm_emc_parents, 0x350, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data mm_ahb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_ahb, "mm-ahb", mm_ahb_parents, 0x354, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data bpc_clk_parents[] = { + { .hw = &twpll_192m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, + { .hw = &dpll0_622m3.hw }, +}; +static SPRD_MUX_CLK_DATA(bpc_clk, "bpc-clk", bpc_clk_parents, 0x358, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data dcam_if_parents[] = { + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(dcam_if_clk, "dcam-if-clk", dcam_if_parents, 0x35c, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data isp_parents[] = { + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, +}; +static SPRD_MUX_CLK_DATA(isp_clk, "isp-clk", isp_parents, 0x360, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data jpg_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, +}; +static SPRD_MUX_CLK_DATA(jpg_clk, "jpg-clk", jpg_parents, 0x364, + 0, 2, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(cpp_clk, "cpp-clk", jpg_parents, 0x368, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data sensor_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_COMP_CLK_DATA(sensor0_clk, "sensor0-clk", sensor_parents, 0x36c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(sensor1_clk, "sensor1-clk", sensor_parents, 0x370, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(sensor2_clk, "sensor2-clk", sensor_parents, 0x374, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data mm_vemc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_vemc, "mm-vemc", mm_vemc_parents, 0x378, + 0, 2, SC9863A_MUX_FLAG); + +static SPRD_MUX_CLK_DATA(mm_vahb, "mm-vahb", mm_ahb_parents, 0x37c, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data vsp_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(clk_vsp, "vsp-clk", vsp_parents, 0x380, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data core_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_512m.hw }, + { .hw = &twpll_768m.hw }, + { .hw = &lpll.common.hw }, + { .hw = &dpll0.common.hw }, + { .hw = &mpll2.common.hw }, + { .hw = &mpll0.common.hw }, + { .hw = &mpll1.common.hw }, +}; +static SPRD_COMP_CLK_DATA(core0_clk, "core0-clk", core_parents, 0xa20, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core1_clk, "core1-clk", core_parents, 0xa24, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core2_clk, "core2-clk", core_parents, 0xa28, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core3_clk, "core3-clk", core_parents, 0xa2c, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core4_clk, "core4-clk", core_parents, 0xa30, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core5_clk, "core5-clk", core_parents, 0xa34, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core6_clk, "core6-clk", core_parents, 0xa38, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core7_clk, "core7-clk", core_parents, 0xa3c, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(scu_clk, "scu-clk", core_parents, 0xa40, + 0, 3, 8, 3, 0); + +static SPRD_DIV_CLK_HW(ace_clk, "ace-clk", &scu_clk.common.hw, 0xa44, + 8, 3, 0); +static SPRD_DIV_CLK_HW(axi_periph_clk, "axi-periph-clk", &scu_clk.common.hw, 0xa48, + 8, 3, 0); +static SPRD_DIV_CLK_HW(axi_acp_clk, "axi-acp-clk", &scu_clk.common.hw, 0xa4c, + 8, 3, 0); + +static const struct clk_parent_data atb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &mpll2.common.hw }, +}; +static SPRD_COMP_CLK_DATA(atb_clk, "atb-clk", atb_parents, 0xa50, + 0, 2, 8, 3, 0); +static SPRD_DIV_CLK_HW(debug_apb_clk, "debug-apb-clk", &atb_clk.common.hw, 0xa54, + 8, 3, 0); + +static const struct clk_parent_data gic_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_COMP_CLK_DATA(gic_clk, "gic-clk", gic_parents, 0xa58, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(periph_clk, "periph-clk", gic_parents, 0xa5c, + 0, 2, 8, 3, 0); + +static struct sprd_clk_common *sc9863a_aon_clks[] = { + /* address base is 0x402d0000 */ + &emc_clk.common, + &aon_apb.common, + &adi_clk.common, + &aux0_clk.common, + &aux1_clk.common, + &aux2_clk.common, + &probe_clk.common, + &pwm0_clk.common, + &pwm1_clk.common, + &pwm2_clk.common, + &aon_thm_clk.common, + &audif_clk.common, + &cpu_dap_clk.common, + &cpu_ts_clk.common, + &djtag_tck_clk.common, + &emc_ref_clk.common, + &cssys_clk.common, + &aon_pmu_clk.common, + &pmu_26m_clk.common, + &aon_tmr_clk.common, + &power_cpu_clk.common, + &ap_axi.common, + &sdio0_2x.common, + &sdio1_2x.common, + &sdio2_2x.common, + &emmc_2x.common, + &dpu_clk.common, + &dpu_dpi.common, + &otg_ref_clk.common, + &sdphy_apb_clk.common, + &alg_io_apb_clk.common, + &gpu_core.common, + &gpu_soc.common, + &mm_emc.common, + &mm_ahb.common, + &bpc_clk.common, + &dcam_if_clk.common, + &isp_clk.common, + &jpg_clk.common, + &cpp_clk.common, + &sensor0_clk.common, + &sensor1_clk.common, + &sensor2_clk.common, + &mm_vemc.common, + &mm_vahb.common, + &clk_vsp.common, + &core0_clk.common, + &core1_clk.common, + &core2_clk.common, + &core3_clk.common, + &core4_clk.common, + &core5_clk.common, + &core6_clk.common, + &core7_clk.common, + &scu_clk.common, + &ace_clk.common, + &axi_periph_clk.common, + &axi_acp_clk.common, + &atb_clk.common, + &debug_apb_clk.common, + &gic_clk.common, + &periph_clk.common, +}; + +static struct clk_hw_onecell_data sc9863a_aon_clk_hws = { + .hws = { + [CLK_13M] = &clk_13m.hw, + [CLK_6M5] = &clk_6m5.hw, + [CLK_4M3] = &clk_4m3.hw, + [CLK_2M] = &clk_2m.hw, + [CLK_250K] = &clk_250k.hw, + [CLK_RCO_25M] = &rco_25m.hw, + [CLK_RCO_4M] = &rco_4m.hw, + [CLK_RCO_2M] = &rco_2m.hw, + [CLK_EMC] = &emc_clk.common.hw, + [CLK_AON_APB] = &aon_apb.common.hw, + [CLK_ADI] = &adi_clk.common.hw, + [CLK_AUX0] = &aux0_clk.common.hw, + [CLK_AUX1] = &aux1_clk.common.hw, + [CLK_AUX2] = &aux2_clk.common.hw, + [CLK_PROBE] = &probe_clk.common.hw, + [CLK_PWM0] = &pwm0_clk.common.hw, + [CLK_PWM1] = &pwm1_clk.common.hw, + [CLK_PWM2] = &pwm2_clk.common.hw, + [CLK_AON_THM] = &aon_thm_clk.common.hw, + [CLK_AUDIF] = &audif_clk.common.hw, + [CLK_CPU_DAP] = &cpu_dap_clk.common.hw, + [CLK_CPU_TS] = &cpu_ts_clk.common.hw, + [CLK_DJTAG_TCK] = &djtag_tck_clk.common.hw, + [CLK_EMC_REF] = &emc_ref_clk.common.hw, + [CLK_CSSYS] = &cssys_clk.common.hw, + [CLK_AON_PMU] = &aon_pmu_clk.common.hw, + [CLK_PMU_26M] = &pmu_26m_clk.common.hw, + [CLK_AON_TMR] = &aon_tmr_clk.common.hw, + [CLK_POWER_CPU] = &power_cpu_clk.common.hw, + [CLK_AP_AXI] = &ap_axi.common.hw, + [CLK_SDIO0_2X] = &sdio0_2x.common.hw, + [CLK_SDIO1_2X] = &sdio1_2x.common.hw, + [CLK_SDIO2_2X] = &sdio2_2x.common.hw, + [CLK_EMMC_2X] = &emmc_2x.common.hw, + [CLK_DPU] = &dpu_clk.common.hw, + [CLK_DPU_DPI] = &dpu_dpi.common.hw, + [CLK_OTG_REF] = &otg_ref_clk.common.hw, + [CLK_SDPHY_APB] = &sdphy_apb_clk.common.hw, + [CLK_ALG_IO_APB] = &alg_io_apb_clk.common.hw, + [CLK_GPU_CORE] = &gpu_core.common.hw, + [CLK_GPU_SOC] = &gpu_soc.common.hw, + [CLK_MM_EMC] = &mm_emc.common.hw, + [CLK_MM_AHB] = &mm_ahb.common.hw, + [CLK_BPC] = &bpc_clk.common.hw, + [CLK_DCAM_IF] = &dcam_if_clk.common.hw, + [CLK_ISP] = &isp_clk.common.hw, + [CLK_JPG] = &jpg_clk.common.hw, + [CLK_CPP] = &cpp_clk.common.hw, + [CLK_SENSOR0] = &sensor0_clk.common.hw, + [CLK_SENSOR1] = &sensor1_clk.common.hw, + [CLK_SENSOR2] = &sensor2_clk.common.hw, + [CLK_MM_VEMC] = &mm_vemc.common.hw, + [CLK_MM_VAHB] = &mm_vahb.common.hw, + [CLK_VSP] = &clk_vsp.common.hw, + [CLK_CORE0] = &core0_clk.common.hw, + [CLK_CORE1] = &core1_clk.common.hw, + [CLK_CORE2] = &core2_clk.common.hw, + [CLK_CORE3] = &core3_clk.common.hw, + [CLK_CORE4] = &core4_clk.common.hw, + [CLK_CORE5] = &core5_clk.common.hw, + [CLK_CORE6] = &core6_clk.common.hw, + [CLK_CORE7] = &core7_clk.common.hw, + [CLK_SCU] = &scu_clk.common.hw, + [CLK_ACE] = &ace_clk.common.hw, + [CLK_AXI_PERIPH] = &axi_periph_clk.common.hw, + [CLK_AXI_ACP] = &axi_acp_clk.common.hw, + [CLK_ATB] = &atb_clk.common.hw, + [CLK_DEBUG_APB] = &debug_apb_clk.common.hw, + [CLK_GIC] = &gic_clk.common.hw, + [CLK_PERIPH] = &periph_clk.common.hw, + }, + .num = CLK_AON_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9863a_aon_clk_desc = { + .clk_clks = sc9863a_aon_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_aon_clks), + .hw_clks = &sc9863a_aon_clk_hws, +}; + +static const struct clk_parent_data ap_apb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_apb, "ap-apb", ap_apb_parents, 0x20, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data ap_ce_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_256m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_ce, "ap-ce", ap_ce_parents, 0x24, + 0, 1, 8, 3, 0); + +static const struct clk_parent_data nandc_ecc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, +}; +static SPRD_COMP_CLK_DATA(nandc_ecc, "nandc-ecc", nandc_ecc_parents, 0x28, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data nandc_26m_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(nandc_26m, "nandc-26m", nandc_26m_parents, 0x2c, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(emmc_32k, "emmc-32k", nandc_26m_parents, 0x30, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio0_32k, "sdio0-32k", nandc_26m_parents, 0x34, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio1_32k, "sdio1-32k", nandc_26m_parents, 0x38, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio2_32k, "sdio2-32k", nandc_26m_parents, 0x3c, + 0, 1, SC9863A_MUX_FLAG); + +static SPRD_GATE_CLK_HW(otg_utmi, "otg-utmi", &aon_apb.common.hw, 0x40, + BIT(16), 0, 0); + +static const struct clk_parent_data ap_uart_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_uart0, "ap-uart0", ap_uart_parents, 0x44, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart1, "ap-uart1", ap_uart_parents, 0x48, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart2, "ap-uart2", ap_uart_parents, 0x4c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart3, "ap-uart3", ap_uart_parents, 0x50, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart4, "ap-uart4", ap_uart_parents, 0x54, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data i2c_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_i2c0, "ap-i2c0", i2c_parents, 0x58, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c1, "ap-i2c1", i2c_parents, 0x5c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c2, "ap-i2c2", i2c_parents, 0x60, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c3, "ap-i2c3", i2c_parents, 0x64, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c4, "ap-i2c4", i2c_parents, 0x68, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c5, "ap-i2c5", i2c_parents, 0x6c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c6, "ap-i2c6", i2c_parents, 0x70, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data spi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_spi0, "ap-spi0", spi_parents, 0x74, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi1, "ap-spi1", spi_parents, 0x78, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi2, "ap-spi2", spi_parents, 0x7c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi3, "ap-spi3", spi_parents, 0x80, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data iis_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_iis0, "ap-iis0", iis_parents, 0x84, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_iis1, "ap-iis1", iis_parents, 0x88, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_iis2, "ap-iis2", iis_parents, 0x8c, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data sim0_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(sim0, "sim0", sim0_parents, 0x90, + 0, 3, 8, 3, 0); + +static const struct clk_parent_data sim0_32k_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(sim0_32k, "sim0-32k", sim0_32k_parents, 0x94, + 0, 1, SC9863A_MUX_FLAG); + +static struct sprd_clk_common *sc9863a_ap_clks[] = { + /* address base is 0x21500000 */ + &ap_apb.common, + &ap_ce.common, + &nandc_ecc.common, + &nandc_26m.common, + &emmc_32k.common, + &sdio0_32k.common, + &sdio1_32k.common, + &sdio2_32k.common, + &otg_utmi.common, + &ap_uart0.common, + &ap_uart1.common, + &ap_uart2.common, + &ap_uart3.common, + &ap_uart4.common, + &ap_i2c0.common, + &ap_i2c1.common, + &ap_i2c2.common, + &ap_i2c3.common, + &ap_i2c4.common, + &ap_i2c5.common, + &ap_i2c6.common, + &ap_spi0.common, + &ap_spi1.common, + &ap_spi2.common, + &ap_spi3.common, + &ap_iis0.common, + &ap_iis1.common, + &ap_iis2.common, + &sim0.common, + &sim0_32k.common, +}; + +static struct clk_hw_onecell_data sc9863a_ap_clk_hws = { + .hws = { + [CLK_AP_APB] = &ap_apb.common.hw, + [CLK_AP_CE] = &ap_ce.common.hw, + [CLK_NANDC_ECC] = &nandc_ecc.common.hw, + [CLK_NANDC_26M] = &nandc_26m.common.hw, + [CLK_EMMC_32K] = &emmc_32k.common.hw, + [CLK_SDIO0_32K] = &sdio0_32k.common.hw, + [CLK_SDIO1_32K] = &sdio1_32k.common.hw, + [CLK_SDIO2_32K] = &sdio2_32k.common.hw, + [CLK_OTG_UTMI] = &otg_utmi.common.hw, + [CLK_AP_UART0] = &ap_uart0.common.hw, + [CLK_AP_UART1] = &ap_uart1.common.hw, + [CLK_AP_UART2] = &ap_uart2.common.hw, + [CLK_AP_UART3] = &ap_uart3.common.hw, + [CLK_AP_UART4] = &ap_uart4.common.hw, + [CLK_AP_I2C0] = &ap_i2c0.common.hw, + [CLK_AP_I2C1] = &ap_i2c1.common.hw, + [CLK_AP_I2C2] = &ap_i2c2.common.hw, + [CLK_AP_I2C3] = &ap_i2c3.common.hw, + [CLK_AP_I2C4] = &ap_i2c4.common.hw, + [CLK_AP_I2C5] = &ap_i2c5.common.hw, + [CLK_AP_I2C6] = &ap_i2c6.common.hw, + [CLK_AP_SPI0] = &ap_spi0.common.hw, + [CLK_AP_SPI1] = &ap_spi1.common.hw, + [CLK_AP_SPI2] = &ap_spi2.common.hw, + [CLK_AP_SPI3] = &ap_spi3.common.hw, + [CLK_AP_IIS0] = &ap_iis0.common.hw, + [CLK_AP_IIS1] = &ap_iis1.common.hw, + [CLK_AP_IIS2] = &ap_iis2.common.hw, + [CLK_SIM0] = &sim0.common.hw, + [CLK_SIM0_32K] = &sim0_32k.common.hw, + }, + .num = CLK_AP_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9863a_ap_clk_desc = { + .clk_clks = sc9863a_ap_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_ap_clks), + .hw_clks = &sc9863a_ap_clk_hws, +}; + +static SPRD_SC_GATE_CLK_HW(otg_eb, "otg-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(dma_eb, "dma-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(ce_eb, "ce-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_HW(nandc_eb, "nandc-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio0_eb, "sdio0-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio1_eb, "sdio1-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio2_eb, "sdio2-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(emmc_eb, "emmc-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(emmc_32k_eb, "emmc-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio0_32k_eb, "sdio0-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio1_32k_eb, "sdio1-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(29), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio2_32k_eb, "sdio2-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(30), 0, 0); +static SPRD_SC_GATE_CLK_HW(nandc_26m_eb, "nandc-26m-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(31), 0, 0); +static SPRD_SC_GATE_CLK_HW(dma_eb2, "dma-eb2", &ap_axi.common.hw, 0x18, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(ce_eb2, "ce-eb2", &ap_axi.common.hw, 0x18, + 0x1000, BIT(1), 0, 0); + +static struct sprd_clk_common *sc9863a_apahb_gate_clks[] = { + /* address base is 0x20e00000 */ + &otg_eb.common, + &dma_eb.common, + &ce_eb.common, + &nandc_eb.common, + &sdio0_eb.common, + &sdio1_eb.common, + &sdio2_eb.common, + &emmc_eb.common, + &emmc_32k_eb.common, + &sdio0_32k_eb.common, + &sdio1_32k_eb.common, + &sdio2_32k_eb.common, + &nandc_26m_eb.common, + &dma_eb2.common, + &ce_eb2.common, +}; + +static struct clk_hw_onecell_data sc9863a_apahb_gate_hws = { + .hws = { + [CLK_OTG_EB] = &otg_eb.common.hw, + [CLK_DMA_EB] = &dma_eb.common.hw, + [CLK_CE_EB] = &ce_eb.common.hw, + [CLK_NANDC_EB] = &nandc_eb.common.hw, + [CLK_SDIO0_EB] = &sdio0_eb.common.hw, + [CLK_SDIO1_EB] = &sdio1_eb.common.hw, + [CLK_SDIO2_EB] = &sdio2_eb.common.hw, + [CLK_EMMC_EB] = &emmc_eb.common.hw, + [CLK_EMMC_32K_EB] = &emmc_32k_eb.common.hw, + [CLK_SDIO0_32K_EB] = &sdio0_32k_eb.common.hw, + [CLK_SDIO1_32K_EB] = &sdio1_32k_eb.common.hw, + [CLK_SDIO2_32K_EB] = &sdio2_32k_eb.common.hw, + [CLK_NANDC_26M_EB] = &nandc_26m_eb.common.hw, + [CLK_DMA_EB2] = &dma_eb2.common.hw, + [CLK_CE_EB2] = &ce_eb2.common.hw, + }, + .num = CLK_AP_AHB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_apahb_gate_desc = { + .clk_clks = sc9863a_apahb_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_apahb_gate_clks), + .hw_clks = &sc9863a_apahb_gate_hws, +}; + +/* aon gate clocks */ +static SPRD_SC_GATE_CLK_HW(gpio_eb, "gpio-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(pwm0_eb, "pwm0-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(pwm1_eb, "pwm1-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(pwm2_eb, "pwm2-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_HW(pwm3_eb, "pwm3-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(kpd_eb, "kpd-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_syst_eb, "aon-syst-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_syst_eb, "ap-syst-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aon_tmr_eb, "aon-tmr-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(efuse_eb, "efuse-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(eic_eb, "eic-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(intc_eb, "intc-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(adi_eb, "adi-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(audif_eb, "audif-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_HW(aud_eb, "aud-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_HW(vbc_eb, "vbc-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_HW(pin_eb, "pin-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_wdg_eb, "ap-wdg-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(24), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_eb, "mm-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(25), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aon_apb_ckg_eb, "aon-apb-ckg-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(26), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_ts0_eb, "ca53-ts0-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(28), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_ts1_eb, "ca53-ts1-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(29), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_dap_eb, "ca53-dap-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(30), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(pmu_eb, "pmu-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(thm_eb, "thm-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aux0_eb, "aux0-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aux1_eb, "aux1-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(aux2_eb, "aux2-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(probe_eb, "probe-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(emc_ref_eb, "emc-ref-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_wdg_eb, "ca53-wdg-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr1_eb, "ap-tmr1-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr2_eb, "ap-tmr2-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(disp_emc_eb, "disp-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(zip_emc_eb, "zip-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_HW(gsp_emc_eb, "gsp-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_vsp_eb, "mm-vsp-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(mdar_eb, "mdar-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_HW(rtc4m0_cal_eb, "rtc4m0-cal-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_HW(rtc4m1_cal_eb, "rtc4m1-cal-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_HW(djtag_eb, "djtag-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_HW(mbox_eb, "mbox-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(21), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_dma_eb, "aon-dma-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(22), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_apb_def_eb, "aon-apb-def-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_HW(ca5_ts0_eb, "ca5-ts0-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_HW(dbg_eb, "dbg-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_HW(dbg_emc_eb, "dbg-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(29), 0, 0); +static SPRD_SC_GATE_CLK_HW(cross_trig_eb, "cross-trig-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(30), 0, 0); +static SPRD_SC_GATE_CLK_HW(serdes_dphy_eb, "serdes-dphy-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(31), 0, 0); +static SPRD_SC_GATE_CLK_HW(arch_rtc_eb, "arch-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(kpd_rtc_eb, "kpd-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_syst_rtc_eb, "aon-syst-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_syst_rtc_eb, "ap-syst-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(eic_rtc_eb, "eic-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(eic_rtcdv5_eb, "eic-rtcdv5-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_wdg_rtc_eb, "ca53-wdg-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(thm_rtc_eb, "thm-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(athma_rtc_eb, "athma-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(gthma_rtc_eb, "gthma-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_HW(athma_rtc_a_eb, "athma-rtc-a-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_HW(gthma_rtc_a_eb, "gthma-rtc-a-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_HW(dxco_lc_rtc_eb, "dxco-lc-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_HW(bb_cal_rtc_eb, "bb-cal-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_HW(gpu_eb, "gpu-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(disp_eb, "disp-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_emc_eb, "mm-emc-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(power_cpu_eb, "power-cpu-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(hw_i2c_eb, "hw-i2c-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_vsp_emc_eb, "mm-vsp-emc-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(vsp_eb, "vsp-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_HW(cssys_eb, "cssys-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(dmc_eb, "dmc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(rosc_eb, "rosc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(s_d_cfg_eb, "s-d-cfg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(s_d_ref_eb, "s-d-ref-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(b_dma_eb, "b-dma-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(anlg_eb, "anlg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(anlg_apb_eb, "anlg-apb-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_HW(bsmtmr_eb, "bsmtmr-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_axi_eb, "ap-axi-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc0_eb, "ap-intc0-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc1_eb, "ap-intc1-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc2_eb, "ap-intc2-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc3_eb, "ap-intc3-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc4_eb, "ap-intc4-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc5_eb, "ap-intc5-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(scc_eb, "scc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(22), 0, 0); +static SPRD_SC_GATE_CLK_HW(dphy_cfg_eb, "dphy-cfg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(23), 0, 0); +static SPRD_SC_GATE_CLK_HW(dphy_ref_eb, "dphy-ref-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(24), 0, 0); +static SPRD_SC_GATE_CLK_HW(cphy_cfg_eb, "cphy-cfg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_HW(otg_ref_eb, "otg-ref-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_HW(serdes_eb, "serdes-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_ap_emc_eb, "aon-ap-emc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(28), 0, 0); +static struct sprd_clk_common *sc9863a_aonapb_gate_clks[] = { + /* address base is 0x402e0000 */ + &gpio_eb.common, + &pwm0_eb.common, + &pwm1_eb.common, + &pwm2_eb.common, + &pwm3_eb.common, + &kpd_eb.common, + &aon_syst_eb.common, + &ap_syst_eb.common, + &aon_tmr_eb.common, + &efuse_eb.common, + &eic_eb.common, + &intc_eb.common, + &adi_eb.common, + &audif_eb.common, + &aud_eb.common, + &vbc_eb.common, + &pin_eb.common, + &ap_wdg_eb.common, + &mm_eb.common, + &aon_apb_ckg_eb.common, + &ca53_ts0_eb.common, + &ca53_ts1_eb.common, + &ca53_dap_eb.common, + &pmu_eb.common, + &thm_eb.common, + &aux0_eb.common, + &aux1_eb.common, + &aux2_eb.common, + &probe_eb.common, + &emc_ref_eb.common, + &ca53_wdg_eb.common, + &ap_tmr1_eb.common, + &ap_tmr2_eb.common, + &disp_emc_eb.common, + &zip_emc_eb.common, + &gsp_emc_eb.common, + &mm_vsp_eb.common, + &mdar_eb.common, + &rtc4m0_cal_eb.common, + &rtc4m1_cal_eb.common, + &djtag_eb.common, + &mbox_eb.common, + &aon_dma_eb.common, + &aon_apb_def_eb.common, + &ca5_ts0_eb.common, + &dbg_eb.common, + &dbg_emc_eb.common, + &cross_trig_eb.common, + &serdes_dphy_eb.common, + &arch_rtc_eb.common, + &kpd_rtc_eb.common, + &aon_syst_rtc_eb.common, + &ap_syst_rtc_eb.common, + &aon_tmr_rtc_eb.common, + &ap_tmr0_rtc_eb.common, + &eic_rtc_eb.common, + &eic_rtcdv5_eb.common, + &ap_wdg_rtc_eb.common, + &ca53_wdg_rtc_eb.common, + &thm_rtc_eb.common, + &athma_rtc_eb.common, + >hma_rtc_eb.common, + &athma_rtc_a_eb.common, + >hma_rtc_a_eb.common, + &ap_tmr1_rtc_eb.common, + &ap_tmr2_rtc_eb.common, + &dxco_lc_rtc_eb.common, + &bb_cal_rtc_eb.common, + &gpu_eb.common, + &disp_eb.common, + &mm_emc_eb.common, + &power_cpu_eb.common, + &hw_i2c_eb.common, + &mm_vsp_emc_eb.common, + &vsp_eb.common, + &cssys_eb.common, + &dmc_eb.common, + &rosc_eb.common, + &s_d_cfg_eb.common, + &s_d_ref_eb.common, + &b_dma_eb.common, + &anlg_eb.common, + &anlg_apb_eb.common, + &bsmtmr_eb.common, + &ap_axi_eb.common, + &ap_intc0_eb.common, + &ap_intc1_eb.common, + &ap_intc2_eb.common, + &ap_intc3_eb.common, + &ap_intc4_eb.common, + &ap_intc5_eb.common, + &scc_eb.common, + &dphy_cfg_eb.common, + &dphy_ref_eb.common, + &cphy_cfg_eb.common, + &otg_ref_eb.common, + &serdes_eb.common, + &aon_ap_emc_eb.common, +}; + +static struct clk_hw_onecell_data sc9863a_aonapb_gate_hws = { + .hws = { + [CLK_GPIO_EB] = &gpio_eb.common.hw, + [CLK_PWM0_EB] = &pwm0_eb.common.hw, + [CLK_PWM1_EB] = &pwm1_eb.common.hw, + [CLK_PWM2_EB] = &pwm2_eb.common.hw, + [CLK_PWM3_EB] = &pwm3_eb.common.hw, + [CLK_KPD_EB] = &kpd_eb.common.hw, + [CLK_AON_SYST_EB] = &aon_syst_eb.common.hw, + [CLK_AP_SYST_EB] = &ap_syst_eb.common.hw, + [CLK_AON_TMR_EB] = &aon_tmr_eb.common.hw, + [CLK_EFUSE_EB] = &efuse_eb.common.hw, + [CLK_EIC_EB] = &eic_eb.common.hw, + [CLK_INTC_EB] = &intc_eb.common.hw, + [CLK_ADI_EB] = &adi_eb.common.hw, + [CLK_AUDIF_EB] = &audif_eb.common.hw, + [CLK_AUD_EB] = &aud_eb.common.hw, + [CLK_VBC_EB] = &vbc_eb.common.hw, + [CLK_PIN_EB] = &pin_eb.common.hw, + [CLK_AP_WDG_EB] = &ap_wdg_eb.common.hw, + [CLK_MM_EB] = &mm_eb.common.hw, + [CLK_AON_APB_CKG_EB] = &aon_apb_ckg_eb.common.hw, + [CLK_CA53_TS0_EB] = &ca53_ts0_eb.common.hw, + [CLK_CA53_TS1_EB] = &ca53_ts1_eb.common.hw, + [CLK_CS53_DAP_EB] = &ca53_dap_eb.common.hw, + [CLK_PMU_EB] = &pmu_eb.common.hw, + [CLK_THM_EB] = &thm_eb.common.hw, + [CLK_AUX0_EB] = &aux0_eb.common.hw, + [CLK_AUX1_EB] = &aux1_eb.common.hw, + [CLK_AUX2_EB] = &aux2_eb.common.hw, + [CLK_PROBE_EB] = &probe_eb.common.hw, + [CLK_EMC_REF_EB] = &emc_ref_eb.common.hw, + [CLK_CA53_WDG_EB] = &ca53_wdg_eb.common.hw, + [CLK_AP_TMR1_EB] = &ap_tmr1_eb.common.hw, + [CLK_AP_TMR2_EB] = &ap_tmr2_eb.common.hw, + [CLK_DISP_EMC_EB] = &disp_emc_eb.common.hw, + [CLK_ZIP_EMC_EB] = &zip_emc_eb.common.hw, + [CLK_GSP_EMC_EB] = &gsp_emc_eb.common.hw, + [CLK_MM_VSP_EB] = &mm_vsp_eb.common.hw, + [CLK_MDAR_EB] = &mdar_eb.common.hw, + [CLK_RTC4M0_CAL_EB] = &rtc4m0_cal_eb.common.hw, + [CLK_RTC4M1_CAL_EB] = &rtc4m1_cal_eb.common.hw, + [CLK_DJTAG_EB] = &djtag_eb.common.hw, + [CLK_MBOX_EB] = &mbox_eb.common.hw, + [CLK_AON_DMA_EB] = &aon_dma_eb.common.hw, + [CLK_AON_APB_DEF_EB] = &aon_apb_def_eb.common.hw, + [CLK_CA5_TS0_EB] = &ca5_ts0_eb.common.hw, + [CLK_DBG_EB] = &dbg_eb.common.hw, + [CLK_DBG_EMC_EB] = &dbg_emc_eb.common.hw, + [CLK_CROSS_TRIG_EB] = &cross_trig_eb.common.hw, + [CLK_SERDES_DPHY_EB] = &serdes_dphy_eb.common.hw, + [CLK_ARCH_RTC_EB] = &arch_rtc_eb.common.hw, + [CLK_KPD_RTC_EB] = &kpd_rtc_eb.common.hw, + [CLK_AON_SYST_RTC_EB] = &aon_syst_rtc_eb.common.hw, + [CLK_AP_SYST_RTC_EB] = &ap_syst_rtc_eb.common.hw, + [CLK_AON_TMR_RTC_EB] = &aon_tmr_rtc_eb.common.hw, + [CLK_AP_TMR0_RTC_EB] = &ap_tmr0_rtc_eb.common.hw, + [CLK_EIC_RTC_EB] = &eic_rtc_eb.common.hw, + [CLK_EIC_RTCDV5_EB] = &eic_rtcdv5_eb.common.hw, + [CLK_AP_WDG_RTC_EB] = &ap_wdg_rtc_eb.common.hw, + [CLK_CA53_WDG_RTC_EB] = &ca53_wdg_rtc_eb.common.hw, + [CLK_THM_RTC_EB] = &thm_rtc_eb.common.hw, + [CLK_ATHMA_RTC_EB] = &athma_rtc_eb.common.hw, + [CLK_GTHMA_RTC_EB] = >hma_rtc_eb.common.hw, + [CLK_ATHMA_RTC_A_EB] = &athma_rtc_a_eb.common.hw, + [CLK_GTHMA_RTC_A_EB] = >hma_rtc_a_eb.common.hw, + [CLK_AP_TMR1_RTC_EB] = &ap_tmr1_rtc_eb.common.hw, + [CLK_AP_TMR2_RTC_EB] = &ap_tmr2_rtc_eb.common.hw, + [CLK_DXCO_LC_RTC_EB] = &dxco_lc_rtc_eb.common.hw, + [CLK_BB_CAL_RTC_EB] = &bb_cal_rtc_eb.common.hw, + [CLK_GNU_EB] = &gpu_eb.common.hw, + [CLK_DISP_EB] = &disp_eb.common.hw, + [CLK_MM_EMC_EB] = &mm_emc_eb.common.hw, + [CLK_POWER_CPU_EB] = &power_cpu_eb.common.hw, + [CLK_HW_I2C_EB] = &hw_i2c_eb.common.hw, + [CLK_MM_VSP_EMC_EB] = &mm_vsp_emc_eb.common.hw, + [CLK_VSP_EB] = &vsp_eb.common.hw, + [CLK_CSSYS_EB] = &cssys_eb.common.hw, + [CLK_DMC_EB] = &dmc_eb.common.hw, + [CLK_ROSC_EB] = &rosc_eb.common.hw, + [CLK_S_D_CFG_EB] = &s_d_cfg_eb.common.hw, + [CLK_S_D_REF_EB] = &s_d_ref_eb.common.hw, + [CLK_B_DMA_EB] = &b_dma_eb.common.hw, + [CLK_ANLG_EB] = &anlg_eb.common.hw, + [CLK_ANLG_APB_EB] = &anlg_apb_eb.common.hw, + [CLK_BSMTMR_EB] = &bsmtmr_eb.common.hw, + [CLK_AP_AXI_EB] = &ap_axi_eb.common.hw, + [CLK_AP_INTC0_EB] = &ap_intc0_eb.common.hw, + [CLK_AP_INTC1_EB] = &ap_intc1_eb.common.hw, + [CLK_AP_INTC2_EB] = &ap_intc2_eb.common.hw, + [CLK_AP_INTC3_EB] = &ap_intc3_eb.common.hw, + [CLK_AP_INTC4_EB] = &ap_intc4_eb.common.hw, + [CLK_AP_INTC5_EB] = &ap_intc5_eb.common.hw, + [CLK_SCC_EB] = &scc_eb.common.hw, + [CLK_DPHY_CFG_EB] = &dphy_cfg_eb.common.hw, + [CLK_DPHY_REF_EB] = &dphy_ref_eb.common.hw, + [CLK_CPHY_CFG_EB] = &cphy_cfg_eb.common.hw, + [CLK_OTG_REF_EB] = &otg_ref_eb.common.hw, + [CLK_SERDES_EB] = &serdes_eb.common.hw, + [CLK_AON_AP_EMC_EB] = &aon_ap_emc_eb.common.hw, + }, + .num = CLK_AON_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_aonapb_gate_desc = { + .clk_clks = sc9863a_aonapb_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_aonapb_gate_clks), + .hw_clks = &sc9863a_aonapb_gate_hws, +}; + +/* mm gate clocks */ +static SPRD_SC_GATE_CLK_HW(mahb_ckg_eb, "mahb-ckg-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(mdcam_eb, "mdcam-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_HW(misp_eb, "misp-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_HW(mahbcsi_eb, "mahbcsi-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(mcsi_s_eb, "mcsi-s-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(mcsi_t_eb, "mcsi-t-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(5), 0, 0); +static SPRD_GATE_CLK_HW(dcam_axi_eb, "dcam-axi-eb", &mm_ahb.common.hw, 0x8, + BIT(0), 0, 0); +static SPRD_GATE_CLK_HW(isp_axi_eb, "isp-axi-eb", &mm_ahb.common.hw, 0x8, + BIT(1), 0, 0); +static SPRD_GATE_CLK_HW(mcsi_eb, "mcsi-eb", &mm_ahb.common.hw, 0x8, + BIT(2), 0, 0); +static SPRD_GATE_CLK_HW(mcsi_s_ckg_eb, "mcsi-s-ckg-eb", &mm_ahb.common.hw, 0x8, + BIT(3), 0, 0); +static SPRD_GATE_CLK_HW(mcsi_t_ckg_eb, "mcsi-t-ckg-eb", &mm_ahb.common.hw, 0x8, + BIT(4), 0, 0); +static SPRD_GATE_CLK_HW(sensor0_eb, "sensor0-eb", &mm_ahb.common.hw, 0x8, + BIT(5), 0, 0); +static SPRD_GATE_CLK_HW(sensor1_eb, "sensor1-eb", &mm_ahb.common.hw, 0x8, + BIT(6), 0, 0); +static SPRD_GATE_CLK_HW(sensor2_eb, "sensor2-eb", &mm_ahb.common.hw, 0x8, + BIT(7), 0, 0); +static SPRD_GATE_CLK_HW(mcphy_cfg_eb, "mcphy-cfg-eb", &mm_ahb.common.hw, 0x8, + BIT(8), 0, 0); + +static struct sprd_clk_common *sc9863a_mm_gate_clks[] = { + /* address base is 0x60800000 */ + &mahb_ckg_eb.common, + &mdcam_eb.common, + &misp_eb.common, + &mahbcsi_eb.common, + &mcsi_s_eb.common, + &mcsi_t_eb.common, + &dcam_axi_eb.common, + &isp_axi_eb.common, + &mcsi_eb.common, + &mcsi_s_ckg_eb.common, + &mcsi_t_ckg_eb.common, + &sensor0_eb.common, + &sensor1_eb.common, + &sensor2_eb.common, + &mcphy_cfg_eb.common, +}; + +static struct clk_hw_onecell_data sc9863a_mm_gate_hws = { + .hws = { + [CLK_MAHB_CKG_EB] = &mahb_ckg_eb.common.hw, + [CLK_MDCAM_EB] = &mdcam_eb.common.hw, + [CLK_MISP_EB] = &misp_eb.common.hw, + [CLK_MAHBCSI_EB] = &mahbcsi_eb.common.hw, + [CLK_MCSI_S_EB] = &mcsi_s_eb.common.hw, + [CLK_MCSI_T_EB] = &mcsi_t_eb.common.hw, + [CLK_DCAM_AXI_EB] = &dcam_axi_eb.common.hw, + [CLK_ISP_AXI_EB] = &isp_axi_eb.common.hw, + [CLK_MCSI_EB] = &mcsi_eb.common.hw, + [CLK_MCSI_S_CKG_EB] = &mcsi_s_ckg_eb.common.hw, + [CLK_MCSI_T_CKG_EB] = &mcsi_t_ckg_eb.common.hw, + [CLK_SENSOR0_EB] = &sensor0_eb.common.hw, + [CLK_SENSOR1_EB] = &sensor1_eb.common.hw, + [CLK_SENSOR2_EB] = &sensor2_eb.common.hw, + [CLK_MCPHY_CFG_EB] = &mcphy_cfg_eb.common.hw, + }, + .num = CLK_MM_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_mm_gate_desc = { + .clk_clks = sc9863a_mm_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_mm_gate_clks), + .hw_clks = &sc9863a_mm_gate_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m", 0x0, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m", 0x0, + 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis1_eb, "iis1-eb", "ext-26m", 0x0, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis2_eb, "iis2-eb", "ext-26m", 0x0, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi0_eb, "spi0-eb", "ext-26m", 0x0, + 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi1_eb, "spi1-eb", "ext-26m", 0x0, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi2_eb, "spi2-eb", "ext-26m", 0x0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c0_eb, "i2c0-eb", "ext-26m", 0x0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c1_eb, "i2c1-eb", "ext-26m", 0x0, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c2_eb, "i2c2-eb", "ext-26m", 0x0, + 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c3_eb, "i2c3-eb", "ext-26m", 0x0, + 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb, "i2c4-eb", "ext-26m", 0x0, + 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb, "uart0-eb", "ext-26m", 0x0, + 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ext-26m", 0x0, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb, "uart2-eb", "ext-26m", 0x0, + 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart3_eb, "uart3-eb", "ext-26m", 0x0, + 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart4_eb, "uart4-eb", "ext-26m", 0x0, + 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sim0_32k_eb, "sim0_32k-eb", "ext-26m", 0x0, + 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi3_eb, "spi3-eb", "ext-26m", 0x0, + 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c5_eb, "i2c5-eb", "ext-26m", 0x0, + 0x1000, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c6_eb, "i2c6-eb", "ext-26m", 0x0, + 0x1000, BIT(21), 0, 0); + +static struct sprd_clk_common *sc9863a_apapb_gate[] = { + /* address base is 0x71300000 */ + &sim0_eb.common, + &iis0_eb.common, + &iis1_eb.common, + &iis2_eb.common, + &spi0_eb.common, + &spi1_eb.common, + &spi2_eb.common, + &i2c0_eb.common, + &i2c1_eb.common, + &i2c2_eb.common, + &i2c3_eb.common, + &i2c4_eb.common, + &uart0_eb.common, + &uart1_eb.common, + &uart2_eb.common, + &uart3_eb.common, + &uart4_eb.common, + &sim0_32k_eb.common, + &spi3_eb.common, + &i2c5_eb.common, + &i2c6_eb.common, +}; + +static struct clk_hw_onecell_data sc9863a_apapb_gate_hws = { + .hws = { + [CLK_SIM0_EB] = &sim0_eb.common.hw, + [CLK_IIS0_EB] = &iis0_eb.common.hw, + [CLK_IIS1_EB] = &iis1_eb.common.hw, + [CLK_IIS2_EB] = &iis2_eb.common.hw, + [CLK_SPI0_EB] = &spi0_eb.common.hw, + [CLK_SPI1_EB] = &spi1_eb.common.hw, + [CLK_SPI2_EB] = &spi2_eb.common.hw, + [CLK_I2C0_EB] = &i2c0_eb.common.hw, + [CLK_I2C1_EB] = &i2c1_eb.common.hw, + [CLK_I2C2_EB] = &i2c2_eb.common.hw, + [CLK_I2C3_EB] = &i2c3_eb.common.hw, + [CLK_I2C4_EB] = &i2c4_eb.common.hw, + [CLK_UART0_EB] = &uart0_eb.common.hw, + [CLK_UART1_EB] = &uart1_eb.common.hw, + [CLK_UART2_EB] = &uart2_eb.common.hw, + [CLK_UART3_EB] = &uart3_eb.common.hw, + [CLK_UART4_EB] = &uart4_eb.common.hw, + [CLK_SIM0_32K_EB] = &sim0_32k_eb.common.hw, + [CLK_SPI3_EB] = &spi3_eb.common.hw, + [CLK_I2C5_EB] = &i2c5_eb.common.hw, + [CLK_I2C6_EB] = &i2c6_eb.common.hw, + }, + .num = CLK_AP_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_apapb_gate_desc = { + .clk_clks = sc9863a_apapb_gate, + .num_clk_clks = ARRAY_SIZE(sc9863a_apapb_gate), + .hw_clks = &sc9863a_apapb_gate_hws, +}; + +static const struct of_device_id sprd_sc9863a_clk_ids[] = { + { .compatible = "sprd,sc9863a-ap-clk", /* 0x21500000 */ + .data = &sc9863a_ap_clk_desc }, + { .compatible = "sprd,sc9863a-pmu-gate", /* 0x402b0000 */ + .data = &sc9863a_pmu_gate_desc }, + { .compatible = "sprd,sc9863a-pll", /* 0x40353000 */ + .data = &sc9863a_pll_desc }, + { .compatible = "sprd,sc9863a-mpll", /* 0x40359000 */ + .data = &sc9863a_mpll_desc }, + { .compatible = "sprd,sc9863a-rpll", /* 0x4035c000 */ + .data = &sc9863a_rpll_desc }, + { .compatible = "sprd,sc9863a-dpll", /* 0x40363000 */ + .data = &sc9863a_dpll_desc }, + { .compatible = "sprd,sc9863a-aon-clk", /* 0x402d0000 */ + .data = &sc9863a_aon_clk_desc }, + { .compatible = "sprd,sc9863a-apahb-gate", /* 0x20e00000 */ + .data = &sc9863a_apahb_gate_desc }, + { .compatible = "sprd,sc9863a-aonapb-gate", /* 0x402e0000 */ + .data = &sc9863a_aonapb_gate_desc }, + { .compatible = "sprd,sc9863a-mm-gate", /* 0x60800000 */ + .data = &sc9863a_mm_gate_desc }, + { .compatible = "sprd,sc9863a-apapb-gate", /* 0x71300000 */ + .data = &sc9863a_apapb_gate_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, sprd_sc9863a_clk_ids); + +static int sc9863a_clk_probe(struct platform_device *pdev) +{ + const struct sprd_clk_desc *desc; + int ret; + + desc = device_get_match_data(&pdev->dev); + if (!desc) + return -ENODEV; + + ret = sprd_clk_regmap_init(pdev, desc); + if (ret) + return ret; + + return sprd_clk_probe(&pdev->dev, desc->hw_clks); +} + +static struct platform_driver sc9863a_clk_driver = { + .probe = sc9863a_clk_probe, + .driver = { + .name = "sc9863a-clk", + .of_match_table = sprd_sc9863a_clk_ids, + }, +}; +module_platform_driver(sc9863a_clk_driver); + +MODULE_DESCRIPTION("Spreadtrum SC9863A Clock Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index 116e6f826d04..54d1f96f4b68 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -55,10 +55,6 @@ /* All the DRAM gates are exported */ -/* Some more module clocks are exported */ - -#define CLK_MBUS 112 - /* And the DSI and GPU module clock is exported */ #define CLK_NUMBER (CLK_GPU + 1) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index d9668493c3f9..524f33275bc7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -50,8 +50,10 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4, CLK_SET_RATE_PARENT); static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4, CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(rot_div_a83_clk, "rot-div", "pll-de", 0x0c, 0x0c, 4, + CLK_SET_RATE_PARENT); -static struct ccu_common *sun50i_h6_de3_clks[] = { +static struct ccu_common *sun8i_a83t_de2_clks[] = { &mixer0_clk.common, &mixer1_clk.common, &wb_clk.common, @@ -60,16 +62,16 @@ static struct ccu_common *sun50i_h6_de3_clks[] = { &bus_mixer1_clk.common, &bus_wb_clk.common, - &mixer0_div_clk.common, - &mixer1_div_clk.common, - &wb_div_clk.common, + &mixer0_div_a83_clk.common, + &mixer1_div_a83_clk.common, + &wb_div_a83_clk.common, &bus_rot_clk.common, &rot_clk.common, - &rot_div_clk.common, + &rot_div_a83_clk.common, }; -static struct ccu_common *sun8i_a83t_de2_clks[] = { +static struct ccu_common *sun8i_h3_de2_clks[] = { &mixer0_clk.common, &mixer1_clk.common, &wb_clk.common, @@ -78,34 +80,38 @@ static struct ccu_common *sun8i_a83t_de2_clks[] = { &bus_mixer1_clk.common, &bus_wb_clk.common, - &mixer0_div_a83_clk.common, - &mixer1_div_a83_clk.common, - &wb_div_a83_clk.common, + &mixer0_div_clk.common, + &mixer1_div_clk.common, + &wb_div_clk.common, }; -static struct ccu_common *sun8i_h3_de2_clks[] = { +static struct ccu_common *sun8i_v3s_de2_clks[] = { &mixer0_clk.common, - &mixer1_clk.common, &wb_clk.common, &bus_mixer0_clk.common, - &bus_mixer1_clk.common, &bus_wb_clk.common, &mixer0_div_clk.common, - &mixer1_div_clk.common, &wb_div_clk.common, }; -static struct ccu_common *sun8i_v3s_de2_clks[] = { +static struct ccu_common *sun50i_a64_de2_clks[] = { &mixer0_clk.common, + &mixer1_clk.common, &wb_clk.common, &bus_mixer0_clk.common, + &bus_mixer1_clk.common, &bus_wb_clk.common, &mixer0_div_clk.common, + &mixer1_div_clk.common, &wb_div_clk.common, + + &bus_rot_clk.common, + &rot_clk.common, + &rot_div_clk.common, }; static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { @@ -113,16 +119,19 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { [CLK_MIXER0] = &mixer0_clk.common.hw, [CLK_MIXER1] = &mixer1_clk.common.hw, [CLK_WB] = &wb_clk.common.hw, + [CLK_ROT] = &rot_clk.common.hw, [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, [CLK_BUS_WB] = &bus_wb_clk.common.hw, + [CLK_BUS_ROT] = &bus_rot_clk.common.hw, [CLK_MIXER0_DIV] = &mixer0_div_a83_clk.common.hw, [CLK_MIXER1_DIV] = &mixer1_div_a83_clk.common.hw, [CLK_WB_DIV] = &wb_div_a83_clk.common.hw, + [CLK_ROT_DIV] = &rot_div_a83_clk.common.hw, }, - .num = CLK_NUMBER_WITHOUT_ROT, + .num = CLK_NUMBER_WITH_ROT, }; static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = { @@ -156,7 +165,7 @@ static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = { .num = CLK_NUMBER_WITHOUT_ROT, }; -static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = { +static struct clk_hw_onecell_data sun50i_a64_de2_hw_clks = { .hws = { [CLK_MIXER0] = &mixer0_clk.common.hw, [CLK_MIXER1] = &mixer1_clk.common.hw, @@ -179,9 +188,19 @@ static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = { static struct ccu_reset_map sun8i_a83t_de2_resets[] = { [RST_MIXER0] = { 0x08, BIT(0) }, /* - * For A83T, H3 and R40, mixer1 reset line is shared with wb, so - * only RST_WB is exported here. - * For V3s there's just no mixer1, so it also shares this struct. + * Mixer1 reset line is shared with wb, so only RST_WB is + * exported here. + */ + [RST_WB] = { 0x08, BIT(2) }, + [RST_ROT] = { 0x08, BIT(3) }, +}; + +static struct ccu_reset_map sun8i_h3_de2_resets[] = { + [RST_MIXER0] = { 0x08, BIT(0) }, + /* + * Mixer1 reset line is shared with wb, so only RST_WB is + * exported here. + * V3s doesn't have mixer1, so it also shares this struct. */ [RST_WB] = { 0x08, BIT(2) }, }; @@ -190,13 +209,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] = { [RST_MIXER0] = { 0x08, BIT(0) }, [RST_MIXER1] = { 0x08, BIT(1) }, [RST_WB] = { 0x08, BIT(2) }, + [RST_ROT] = { 0x08, BIT(3) }, }; -static struct ccu_reset_map sun50i_h6_de3_resets[] = { +static struct ccu_reset_map sun50i_h5_de2_resets[] = { [RST_MIXER0] = { 0x08, BIT(0) }, [RST_MIXER1] = { 0x08, BIT(1) }, [RST_WB] = { 0x08, BIT(2) }, - [RST_ROT] = { 0x08, BIT(3) }, }; static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = { @@ -215,28 +234,18 @@ static const struct sunxi_ccu_desc sun8i_h3_de2_clk_desc = { .hw_clks = &sun8i_h3_de2_hw_clks, - .resets = sun8i_a83t_de2_resets, - .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), + .resets = sun8i_h3_de2_resets, + .num_resets = ARRAY_SIZE(sun8i_h3_de2_resets), }; -static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = { - .ccu_clks = sun8i_h3_de2_clks, - .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks), +static const struct sunxi_ccu_desc sun8i_r40_de2_clk_desc = { + .ccu_clks = sun50i_a64_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks), - .hw_clks = &sun8i_h3_de2_hw_clks, + .hw_clks = &sun50i_a64_de2_hw_clks, - .resets = sun50i_a64_de2_resets, - .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets), -}; - -static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = { - .ccu_clks = sun50i_h6_de3_clks, - .num_ccu_clks = ARRAY_SIZE(sun50i_h6_de3_clks), - - .hw_clks = &sun50i_h6_de3_hw_clks, - - .resets = sun50i_h6_de3_resets, - .num_resets = ARRAY_SIZE(sun50i_h6_de3_resets), + .resets = sun8i_a83t_de2_resets, + .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), }; static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = { @@ -249,6 +258,26 @@ static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = { .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), }; +static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = { + .ccu_clks = sun50i_a64_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks), + + .hw_clks = &sun50i_a64_de2_hw_clks, + + .resets = sun50i_a64_de2_resets, + .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets), +}; + +static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { + .ccu_clks = sun8i_h3_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks), + + .hw_clks = &sun8i_h3_de2_hw_clks, + + .resets = sun50i_h5_de2_resets, + .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), +}; + static int sunxi_de2_clk_probe(struct platform_device *pdev) { struct resource *res; @@ -338,6 +367,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { .data = &sun8i_h3_de2_clk_desc, }, { + .compatible = "allwinner,sun8i-r40-de2-clk", + .data = &sun8i_r40_de2_clk_desc, + }, + { .compatible = "allwinner,sun8i-v3s-de2-clk", .data = &sun8i_v3s_de2_clk_desc, }, @@ -347,11 +380,11 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { }, { .compatible = "allwinner,sun50i-h5-de2-clk", - .data = &sun50i_a64_de2_clk_desc, + .data = &sun50i_h5_de2_clk_desc, }, { .compatible = "allwinner,sun50i-h6-de3-clk", - .data = &sun50i_h6_de3_clk_desc, + .data = &sun50i_h5_de2_clk_desc, }, { } }; diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index df966ca06788..1f7c30f87ece 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -12,7 +12,6 @@ obj-y += clk-sdmmc-mux.o obj-y += clk-super.o obj-y += clk-tegra-audio.o obj-y += clk-tegra-periph.o -obj-y += clk-tegra-pmc.o obj-y += clk-tegra-fixed.o obj-y += clk-tegra-super-gen4.o obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index c4faebd32760..ff7da2d3e94d 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -32,7 +32,6 @@ enum clk_id { tegra_clk_audio4, tegra_clk_audio4_2x, tegra_clk_audio4_mux, - tegra_clk_blink, tegra_clk_bsea, tegra_clk_bsev, tegra_clk_cclk_g, @@ -44,14 +43,9 @@ enum clk_id { tegra_clk_clk72Mhz, tegra_clk_clk72Mhz_8, tegra_clk_clk_m, - tegra_clk_clk_m_div2, - tegra_clk_clk_m_div4, - tegra_clk_clk_out_1, - tegra_clk_clk_out_1_mux, - tegra_clk_clk_out_2, - tegra_clk_clk_out_2_mux, - tegra_clk_clk_out_3, - tegra_clk_clk_out_3_mux, + tegra_clk_osc, + tegra_clk_osc_div2, + tegra_clk_osc_div4, tegra_clk_cml0, tegra_clk_cml1, tegra_clk_csi, diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index 7c6c8abfcde6..77c22cef5014 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -46,7 +46,28 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, return -EINVAL; } + dt_clk = tegra_lookup_dt_id(tegra_clk_osc, clks); + if (!dt_clk) + return 0; + osc = clk_register_fixed_rate(NULL, "osc", NULL, 0, *osc_freq); + *dt_clk = osc; + + /* osc_div2 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_osc_div2, clks); + if (dt_clk) { + clk = clk_register_fixed_factor(NULL, "osc_div2", "osc", + 0, 1, 2); + *dt_clk = clk; + } + + /* osc_div4 */ + dt_clk = tegra_lookup_dt_id(tegra_clk_osc_div4, clks); + if (dt_clk) { + clk = clk_register_fixed_factor(NULL, "osc_div4", "osc", + 0, 1, 4); + *dt_clk = clk; + } dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks); if (!dt_clk) @@ -84,22 +105,6 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768); *dt_clk = clk; } - - /* clk_m_div2 */ - dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div2, tegra_clks); - if (dt_clk) { - clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", - CLK_SET_RATE_PARENT, 1, 2); - *dt_clk = clk; - } - - /* clk_m_div4 */ - dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div4, tegra_clks); - if (dt_clk) { - clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", - CLK_SET_RATE_PARENT, 1, 4); - *dt_clk = clk; - } } void tegra_clk_osc_resume(void __iomem *clk_base) diff --git a/drivers/clk/tegra/clk-tegra-pmc.c b/drivers/clk/tegra/clk-tegra-pmc.c deleted file mode 100644 index bec3e008335f..000000000000 --- a/drivers/clk/tegra/clk-tegra-pmc.c +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. - */ - -#include <linux/io.h> -#include <linux/clk-provider.h> -#include <linux/clkdev.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/delay.h> -#include <linux/export.h> -#include <linux/clk/tegra.h> - -#include "clk.h" -#include "clk-id.h" - -#define PMC_CLK_OUT_CNTRL 0x1a8 -#define PMC_DPD_PADS_ORIDE 0x1c -#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 -#define PMC_CTRL 0 -#define PMC_CTRL_BLINK_ENB 7 -#define PMC_BLINK_TIMER 0x40 - -struct pmc_clk_init_data { - char *mux_name; - char *gate_name; - const char **parents; - int num_parents; - int mux_id; - int gate_id; - char *dev_name; - u8 mux_shift; - u8 gate_shift; -}; - -#define PMC_CLK(_num, _mux_shift, _gate_shift)\ - {\ - .mux_name = "clk_out_" #_num "_mux",\ - .gate_name = "clk_out_" #_num,\ - .parents = clk_out ##_num ##_parents,\ - .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\ - .mux_id = tegra_clk_clk_out_ ##_num ##_mux,\ - .gate_id = tegra_clk_clk_out_ ##_num,\ - .dev_name = "extern" #_num,\ - .mux_shift = _mux_shift,\ - .gate_shift = _gate_shift,\ - } - -static DEFINE_SPINLOCK(clk_out_lock); - -static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", -}; - -static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", -}; - -static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", -}; - -static struct pmc_clk_init_data pmc_clks[] = { - PMC_CLK(1, 6, 2), - PMC_CLK(2, 14, 10), - PMC_CLK(3, 22, 18), -}; - -void __init tegra_pmc_clk_init(void __iomem *pmc_base, - struct tegra_clk *tegra_clks) -{ - struct clk *clk; - struct clk **dt_clk; - int i; - - for (i = 0; i < ARRAY_SIZE(pmc_clks); i++) { - struct pmc_clk_init_data *data; - - data = pmc_clks + i; - - dt_clk = tegra_lookup_dt_id(data->mux_id, tegra_clks); - if (!dt_clk) - continue; - - clk = clk_register_mux(NULL, data->mux_name, data->parents, - data->num_parents, - CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, - pmc_base + PMC_CLK_OUT_CNTRL, data->mux_shift, - 3, 0, &clk_out_lock); - *dt_clk = clk; - - - dt_clk = tegra_lookup_dt_id(data->gate_id, tegra_clks); - if (!dt_clk) - continue; - - clk = clk_register_gate(NULL, data->gate_name, data->mux_name, - CLK_SET_RATE_PARENT, - pmc_base + PMC_CLK_OUT_CNTRL, - data->gate_shift, 0, &clk_out_lock); - *dt_clk = clk; - clk_register_clkdev(clk, data->dev_name, data->gate_name); - } - - /* blink */ - writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); - clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, - pmc_base + PMC_DPD_PADS_ORIDE, - PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); - - dt_clk = tegra_lookup_dt_id(tegra_clk_blink, tegra_clks); - if (!dt_clk) - return; - - clk = clk_register_gate(NULL, "blink", "blink_override", 0, - pmc_base + PMC_CTRL, - PMC_CTRL_BLINK_ENB, 0, NULL); - clk_register_clkdev(clk, "blink", NULL); - *dt_clk = clk; -} - diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 4efcaaf51b3a..bc9e47a4cb60 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -735,8 +735,9 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { [tegra_clk_fuse_burn] = { .dt_id = TEGRA114_CLK_FUSE_BURN, .present = true }, [tegra_clk_clk_32k] = { .dt_id = TEGRA114_CLK_CLK_32K, .present = true }, [tegra_clk_clk_m] = { .dt_id = TEGRA114_CLK_CLK_M, .present = true }, - [tegra_clk_clk_m_div2] = { .dt_id = TEGRA114_CLK_CLK_M_DIV2, .present = true }, - [tegra_clk_clk_m_div4] = { .dt_id = TEGRA114_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_osc] = { .dt_id = TEGRA114_CLK_OSC, .present = true }, + [tegra_clk_osc_div2] = { .dt_id = TEGRA114_CLK_OSC_DIV2, .present = true }, + [tegra_clk_osc_div4] = { .dt_id = TEGRA114_CLK_OSC_DIV4, .present = true }, [tegra_clk_pll_ref] = { .dt_id = TEGRA114_CLK_PLL_REF, .present = true }, [tegra_clk_pll_c] = { .dt_id = TEGRA114_CLK_PLL_C, .present = true }, [tegra_clk_pll_c_out1] = { .dt_id = TEGRA114_CLK_PLL_C_OUT1, .present = true }, @@ -778,10 +779,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3] = { .dt_id = TEGRA114_CLK_AUDIO3, .present = true }, [tegra_clk_audio4] = { .dt_id = TEGRA114_CLK_AUDIO4, .present = true }, [tegra_clk_spdif] = { .dt_id = TEGRA114_CLK_SPDIF, .present = true }, - [tegra_clk_clk_out_1] = { .dt_id = TEGRA114_CLK_CLK_OUT_1, .present = true }, - [tegra_clk_clk_out_2] = { .dt_id = TEGRA114_CLK_CLK_OUT_2, .present = true }, - [tegra_clk_clk_out_3] = { .dt_id = TEGRA114_CLK_CLK_OUT_3, .present = true }, - [tegra_clk_blink] = { .dt_id = TEGRA114_CLK_BLINK, .present = true }, [tegra_clk_xusb_host_src] = { .dt_id = TEGRA114_CLK_XUSB_HOST_SRC, .present = true }, [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true }, [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true }, @@ -803,9 +800,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3_mux] = { .dt_id = TEGRA114_CLK_AUDIO3_MUX, .present = true }, [tegra_clk_audio4_mux] = { .dt_id = TEGRA114_CLK_AUDIO4_MUX, .present = true }, [tegra_clk_spdif_mux] = { .dt_id = TEGRA114_CLK_SPDIF_MUX, .present = true }, - [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_1_MUX, .present = true }, - [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_2_MUX, .present = true }, - [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_3_MUX, .present = true }, [tegra_clk_dsia_mux] = { .dt_id = TEGRA114_CLK_DSIA_MUX, .present = true }, [tegra_clk_dsib_mux] = { .dt_id = TEGRA114_CLK_DSIB_MUX, .present = true }, [tegra_clk_cec] = { .dt_id = TEGRA114_CLK_CEC, .present = true }, @@ -815,8 +809,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "clk_m", .dt_id = TEGRA114_CLK_CLK_M }, { .con_id = "pll_ref", .dt_id = TEGRA114_CLK_PLL_REF }, { .con_id = "clk_32k", .dt_id = TEGRA114_CLK_CLK_32K }, - { .con_id = "clk_m_div2", .dt_id = TEGRA114_CLK_CLK_M_DIV2 }, - { .con_id = "clk_m_div4", .dt_id = TEGRA114_CLK_CLK_M_DIV4 }, + { .con_id = "osc", .dt_id = TEGRA114_CLK_OSC }, + { .con_id = "osc_div2", .dt_id = TEGRA114_CLK_OSC_DIV2 }, + { .con_id = "osc_div4", .dt_id = TEGRA114_CLK_OSC_DIV4 }, { .con_id = "pll_c", .dt_id = TEGRA114_CLK_PLL_C }, { .con_id = "pll_c_out1", .dt_id = TEGRA114_CLK_PLL_C_OUT1 }, { .con_id = "pll_c2", .dt_id = TEGRA114_CLK_PLL_C2 }, @@ -863,10 +858,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "audio3_2x", .dt_id = TEGRA114_CLK_AUDIO3_2X }, { .con_id = "audio4_2x", .dt_id = TEGRA114_CLK_AUDIO4_2X }, { .con_id = "spdif_2x", .dt_id = TEGRA114_CLK_SPDIF_2X }, - { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA114_CLK_EXTERN1 }, - { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA114_CLK_EXTERN2 }, - { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA114_CLK_EXTERN3 }, - { .con_id = "blink", .dt_id = TEGRA114_CLK_BLINK }, + { .con_id = "extern1", .dt_id = TEGRA114_CLK_EXTERN1 }, + { .con_id = "extern2", .dt_id = TEGRA114_CLK_EXTERN2 }, + { .con_id = "extern3", .dt_id = TEGRA114_CLK_EXTERN3 }, { .con_id = "cclk_g", .dt_id = TEGRA114_CLK_CCLK_G }, { .con_id = "cclk_lp", .dt_id = TEGRA114_CLK_CCLK_LP }, { .con_id = "sclk", .dt_id = TEGRA114_CLK_SCLK }, @@ -900,17 +894,6 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) /* clk_32k */ clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768); clks[TEGRA114_CLK_CLK_32K] = clk; - - /* clk_m_div2 */ - clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", - CLK_SET_RATE_PARENT, 1, 2); - clks[TEGRA114_CLK_CLK_M_DIV2] = clk; - - /* clk_m_div4 */ - clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", - CLK_SET_RATE_PARENT, 1, 4); - clks[TEGRA114_CLK_CLK_M_DIV4] = clk; - } static void __init tegra114_pll_init(void __iomem *clk_base, @@ -1153,11 +1136,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA114_CLK_UARTB, TEGRA114_CLK_PLL_P, 408000000, 0 }, { TEGRA114_CLK_UARTC, TEGRA114_CLK_PLL_P, 408000000, 0 }, { TEGRA114_CLK_UARTD, TEGRA114_CLK_PLL_P, 408000000, 0 }, - { TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1 }, - { TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1 }, - { TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1 }, - { TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1 }, - { TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1 }, + { TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 0 }, + { TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 0 }, { TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, @@ -1359,7 +1339,6 @@ static void __init tegra114_clock_init(struct device_node *np) tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, tegra114_audio_plls, ARRAY_SIZE(tegra114_audio_plls), 24000000); - tegra_pmc_clk_init(pmc_base, tegra114_clks); tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, &pll_x_params); diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index b3110d5b5a6c..64e229ddf2a5 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -860,8 +860,9 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true }, [tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true }, [tegra_clk_clk_m] = { .dt_id = TEGRA124_CLK_CLK_M, .present = true }, - [tegra_clk_clk_m_div2] = { .dt_id = TEGRA124_CLK_CLK_M_DIV2, .present = true }, - [tegra_clk_clk_m_div4] = { .dt_id = TEGRA124_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_osc] = { .dt_id = TEGRA124_CLK_OSC, .present = true }, + [tegra_clk_osc_div2] = { .dt_id = TEGRA124_CLK_OSC_DIV2, .present = true }, + [tegra_clk_osc_div4] = { .dt_id = TEGRA124_CLK_OSC_DIV4, .present = true }, [tegra_clk_pll_ref] = { .dt_id = TEGRA124_CLK_PLL_REF, .present = true }, [tegra_clk_pll_c] = { .dt_id = TEGRA124_CLK_PLL_C, .present = true }, [tegra_clk_pll_c_out1] = { .dt_id = TEGRA124_CLK_PLL_C_OUT1, .present = true }, @@ -902,10 +903,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true }, [tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true }, [tegra_clk_spdif] = { .dt_id = TEGRA124_CLK_SPDIF, .present = true }, - [tegra_clk_clk_out_1] = { .dt_id = TEGRA124_CLK_CLK_OUT_1, .present = true }, - [tegra_clk_clk_out_2] = { .dt_id = TEGRA124_CLK_CLK_OUT_2, .present = true }, - [tegra_clk_clk_out_3] = { .dt_id = TEGRA124_CLK_CLK_OUT_3, .present = true }, - [tegra_clk_blink] = { .dt_id = TEGRA124_CLK_BLINK, .present = true }, [tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true }, [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true }, [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true }, @@ -931,9 +928,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true }, [tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true }, [tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true }, - [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true }, - [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true }, - [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, [tegra_clk_cec] = { .dt_id = TEGRA124_CLK_CEC, .present = true }, }; @@ -941,8 +935,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "clk_m", .dt_id = TEGRA124_CLK_CLK_M }, { .con_id = "pll_ref", .dt_id = TEGRA124_CLK_PLL_REF }, { .con_id = "clk_32k", .dt_id = TEGRA124_CLK_CLK_32K }, - { .con_id = "clk_m_div2", .dt_id = TEGRA124_CLK_CLK_M_DIV2 }, - { .con_id = "clk_m_div4", .dt_id = TEGRA124_CLK_CLK_M_DIV4 }, + { .con_id = "osc", .dt_id = TEGRA124_CLK_OSC }, + { .con_id = "osc_div2", .dt_id = TEGRA124_CLK_OSC_DIV2 }, + { .con_id = "osc_div4", .dt_id = TEGRA124_CLK_OSC_DIV4 }, { .con_id = "pll_c", .dt_id = TEGRA124_CLK_PLL_C }, { .con_id = "pll_c_out1", .dt_id = TEGRA124_CLK_PLL_C_OUT1 }, { .con_id = "pll_c2", .dt_id = TEGRA124_CLK_PLL_C2 }, @@ -988,10 +983,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "audio3_2x", .dt_id = TEGRA124_CLK_AUDIO3_2X }, { .con_id = "audio4_2x", .dt_id = TEGRA124_CLK_AUDIO4_2X }, { .con_id = "spdif_2x", .dt_id = TEGRA124_CLK_SPDIF_2X }, - { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA124_CLK_EXTERN1 }, - { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA124_CLK_EXTERN2 }, - { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA124_CLK_EXTERN3 }, - { .con_id = "blink", .dt_id = TEGRA124_CLK_BLINK }, + { .con_id = "extern1", .dt_id = TEGRA124_CLK_EXTERN1 }, + { .con_id = "extern2", .dt_id = TEGRA124_CLK_EXTERN2 }, + { .con_id = "extern3", .dt_id = TEGRA124_CLK_EXTERN3 }, { .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G }, { .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP }, { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK }, @@ -1298,11 +1292,8 @@ static struct tegra_clk_init_table common_init_table[] __initdata = { { TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0 }, { TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0 }, { TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0 }, - { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1 }, - { TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1 }, - { TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1 }, - { TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1 }, - { TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1 }, + { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 0 }, + { TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 0 }, { TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, @@ -1457,11 +1448,9 @@ static void __init tegra132_clock_apply_init_table(void) * tegra124_132_clock_init_pre - clock initialization preamble for T124/T132 * @np: struct device_node * of the DT node for the SoC CAR IP block * - * Register most of the clocks controlled by the CAR IP block, along - * with a few clocks controlled by the PMC IP block. Everything in - * this function should be common to Tegra124 and Tegra132. XXX The - * PMC clock initialization should probably be moved to PMC-specific - * driver code. No return value. + * Register most of the clocks controlled by the CAR IP block. + * Everything in this function should be common to Tegra124 and Tegra132. + * No return value. */ static void __init tegra124_132_clock_init_pre(struct device_node *np) { @@ -1504,7 +1493,6 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np) tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, tegra124_audio_plls, ARRAY_SIZE(tegra124_audio_plls), 24576000); - tegra_pmc_clk_init(pmc_base, tegra124_clks); /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */ plld_base = readl(clk_base + PLLD_BASE); @@ -1516,11 +1504,11 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np) * tegra124_132_clock_init_post - clock initialization postamble for T124/T132 * @np: struct device_node * of the DT node for the SoC CAR IP block * - * Register most of the along with a few clocks controlled by the PMC - * IP block. Everything in this function should be common to Tegra124 + * Register most of the clocks controlled by the CAR IP block. + * Everything in this function should be common to Tegra124 * and Tegra132. This function must be called after - * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will - * not be set. No return value. + * tegra124_132_clock_init_pre(), otherwise clk_base will not be set. + * No return value. */ static void __init tegra124_132_clock_init_post(struct device_node *np) { diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index fff5cba87637..085feb04e913 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -458,7 +458,6 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, - { .con_id = "blink", .dt_id = TEGRA20_CLK_BLINK }, { .con_id = "clk_m", .dt_id = TEGRA20_CLK_CLK_M }, { .con_id = "pll_ref", .dt_id = TEGRA20_CLK_PLL_REF }, { .dev_id = "tegra20-i2s.0", .dt_id = TEGRA20_CLK_I2S1 }, @@ -537,7 +536,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { [tegra_clk_csi] = { .dt_id = TEGRA20_CLK_CSI, .present = true }, [tegra_clk_isp] = { .dt_id = TEGRA20_CLK_ISP, .present = true }, [tegra_clk_clk_32k] = { .dt_id = TEGRA20_CLK_CLK_32K, .present = true }, - [tegra_clk_blink] = { .dt_id = TEGRA20_CLK_BLINK, .present = true }, [tegra_clk_hclk] = { .dt_id = TEGRA20_CLK_HCLK, .present = true }, [tegra_clk_pclk] = { .dt_id = TEGRA20_CLK_PCLK, .present = true }, [tegra_clk_pll_p_out1] = { .dt_id = TEGRA20_CLK_PLL_P_OUT1, .present = true }, @@ -1031,10 +1029,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0 }, { TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0 }, { TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0 }, - { TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1 }, - { TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1 }, - { TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1 }, - { TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1 }, + { TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 0 }, + { TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 0 }, { TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0 }, @@ -1146,7 +1142,6 @@ static void __init tegra20_clock_init(struct device_node *np) tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL); tegra20_periph_clk_init(); tegra20_audio_clk_init(); - tegra_pmc_clk_init(pmc_base, tegra20_clks); tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX); diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 762cd186f714..defe3b7ebfa4 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -2371,8 +2371,9 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_fuse_burn] = { .dt_id = TEGRA210_CLK_FUSE_BURN, .present = true }, [tegra_clk_clk_32k] = { .dt_id = TEGRA210_CLK_CLK_32K, .present = true }, [tegra_clk_clk_m] = { .dt_id = TEGRA210_CLK_CLK_M, .present = true }, - [tegra_clk_clk_m_div2] = { .dt_id = TEGRA210_CLK_CLK_M_DIV2, .present = true }, - [tegra_clk_clk_m_div4] = { .dt_id = TEGRA210_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_osc] = { .dt_id = TEGRA210_CLK_OSC, .present = true }, + [tegra_clk_osc_div2] = { .dt_id = TEGRA210_CLK_OSC_DIV2, .present = true }, + [tegra_clk_osc_div4] = { .dt_id = TEGRA210_CLK_OSC_DIV4, .present = true }, [tegra_clk_pll_ref] = { .dt_id = TEGRA210_CLK_PLL_REF, .present = true }, [tegra_clk_pll_c] = { .dt_id = TEGRA210_CLK_PLL_C, .present = true }, [tegra_clk_pll_c_out1] = { .dt_id = TEGRA210_CLK_PLL_C_OUT1, .present = true }, @@ -2417,10 +2418,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3] = { .dt_id = TEGRA210_CLK_AUDIO3, .present = true }, [tegra_clk_audio4] = { .dt_id = TEGRA210_CLK_AUDIO4, .present = true }, [tegra_clk_spdif] = { .dt_id = TEGRA210_CLK_SPDIF, .present = true }, - [tegra_clk_clk_out_1] = { .dt_id = TEGRA210_CLK_CLK_OUT_1, .present = true }, - [tegra_clk_clk_out_2] = { .dt_id = TEGRA210_CLK_CLK_OUT_2, .present = true }, - [tegra_clk_clk_out_3] = { .dt_id = TEGRA210_CLK_CLK_OUT_3, .present = true }, - [tegra_clk_blink] = { .dt_id = TEGRA210_CLK_BLINK, .present = true }, [tegra_clk_xusb_gate] = { .dt_id = TEGRA210_CLK_XUSB_GATE, .present = true }, [tegra_clk_xusb_host_src_8] = { .dt_id = TEGRA210_CLK_XUSB_HOST_SRC, .present = true }, [tegra_clk_xusb_falcon_src_8] = { .dt_id = TEGRA210_CLK_XUSB_FALCON_SRC, .present = true }, @@ -2452,9 +2449,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3_mux] = { .dt_id = TEGRA210_CLK_AUDIO3_MUX, .present = true }, [tegra_clk_audio4_mux] = { .dt_id = TEGRA210_CLK_AUDIO4_MUX, .present = true }, [tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true }, - [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_1_MUX, .present = true }, - [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_2_MUX, .present = true }, - [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_3_MUX, .present = true }, [tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true }, [tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true }, [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true }, @@ -2497,8 +2491,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "clk_m", .dt_id = TEGRA210_CLK_CLK_M }, { .con_id = "pll_ref", .dt_id = TEGRA210_CLK_PLL_REF }, { .con_id = "clk_32k", .dt_id = TEGRA210_CLK_CLK_32K }, - { .con_id = "clk_m_div2", .dt_id = TEGRA210_CLK_CLK_M_DIV2 }, - { .con_id = "clk_m_div4", .dt_id = TEGRA210_CLK_CLK_M_DIV4 }, + { .con_id = "osc", .dt_id = TEGRA210_CLK_OSC }, + { .con_id = "osc_div2", .dt_id = TEGRA210_CLK_OSC_DIV2 }, + { .con_id = "osc_div4", .dt_id = TEGRA210_CLK_OSC_DIV4 }, { .con_id = "pll_c", .dt_id = TEGRA210_CLK_PLL_C }, { .con_id = "pll_c_out1", .dt_id = TEGRA210_CLK_PLL_C_OUT1 }, { .con_id = "pll_c2", .dt_id = TEGRA210_CLK_PLL_C2 }, @@ -2540,10 +2535,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "audio4", .dt_id = TEGRA210_CLK_AUDIO4 }, { .con_id = "spdif", .dt_id = TEGRA210_CLK_SPDIF }, { .con_id = "spdif_2x", .dt_id = TEGRA210_CLK_SPDIF_2X }, - { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA210_CLK_EXTERN1 }, - { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA210_CLK_EXTERN2 }, - { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA210_CLK_EXTERN3 }, - { .con_id = "blink", .dt_id = TEGRA210_CLK_BLINK }, + { .con_id = "extern1", .dt_id = TEGRA210_CLK_EXTERN1 }, + { .con_id = "extern2", .dt_id = TEGRA210_CLK_EXTERN2 }, + { .con_id = "extern3", .dt_id = TEGRA210_CLK_EXTERN3 }, { .con_id = "cclk_g", .dt_id = TEGRA210_CLK_CCLK_G }, { .con_id = "cclk_lp", .dt_id = TEGRA210_CLK_CCLK_LP }, { .con_id = "sclk", .dt_id = TEGRA210_CLK_SCLK }, @@ -2999,7 +2993,7 @@ static const char * const la_parents[] = { }; static struct tegra_clk_periph tegra210_la = - TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0); + TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, NULL); static __init void tegra210_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base) @@ -3448,11 +3442,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA210_CLK_UARTB, TEGRA210_CLK_PLL_P, 408000000, 0 }, { TEGRA210_CLK_UARTC, TEGRA210_CLK_PLL_P, 408000000, 0 }, { TEGRA210_CLK_UARTD, TEGRA210_CLK_PLL_P, 408000000, 0 }, - { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1 }, - { TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 1 }, - { TEGRA210_CLK_EXTERN1, TEGRA210_CLK_PLL_A_OUT0, 0, 1 }, - { TEGRA210_CLK_CLK_OUT_1_MUX, TEGRA210_CLK_EXTERN1, 0, 1 }, - { TEGRA210_CLK_CLK_OUT_1, TEGRA210_CLK_CLK_MAX, 0, 1 }, + { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 0 }, + { TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 0 }, { TEGRA210_CLK_I2S0, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA210_CLK_I2S1, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA210_CLK_I2S2, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, @@ -3693,7 +3684,6 @@ static void __init tegra210_clock_init(struct device_node *np) tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks, tegra210_audio_plls, ARRAY_SIZE(tegra210_audio_plls), 24576000); - tegra_pmc_clk_init(pmc_base, tegra210_clks); /* For Tegra210, PLLD is the only source for DSIA & DSIB */ value = readl(clk_base + PLLD_BASE); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index b20891489e11..3255f82e61b5 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -569,10 +569,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "audio3_2x", .dt_id = TEGRA30_CLK_AUDIO3_2X }, { .con_id = "audio4_2x", .dt_id = TEGRA30_CLK_AUDIO4_2X }, { .con_id = "spdif_2x", .dt_id = TEGRA30_CLK_SPDIF_2X }, - { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA30_CLK_EXTERN1 }, - { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA30_CLK_EXTERN2 }, - { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA30_CLK_EXTERN3 }, - { .con_id = "blink", .dt_id = TEGRA30_CLK_BLINK }, + { .con_id = "extern1", .dt_id = TEGRA30_CLK_EXTERN1 }, + { .con_id = "extern2", .dt_id = TEGRA30_CLK_EXTERN2 }, + { .con_id = "extern3", .dt_id = TEGRA30_CLK_EXTERN3 }, { .con_id = "cclk_g", .dt_id = TEGRA30_CLK_CCLK_G }, { .con_id = "cclk_lp", .dt_id = TEGRA30_CLK_CCLK_LP }, { .con_id = "sclk", .dt_id = TEGRA30_CLK_SCLK }, @@ -581,8 +580,9 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "twd", .dt_id = TEGRA30_CLK_TWD }, { .con_id = "emc", .dt_id = TEGRA30_CLK_EMC }, { .con_id = "clk_32k", .dt_id = TEGRA30_CLK_CLK_32K }, - { .con_id = "clk_m_div2", .dt_id = TEGRA30_CLK_CLK_M_DIV2 }, - { .con_id = "clk_m_div4", .dt_id = TEGRA30_CLK_CLK_M_DIV4 }, + { .con_id = "osc", .dt_id = TEGRA30_CLK_OSC }, + { .con_id = "osc_div2", .dt_id = TEGRA30_CLK_OSC_DIV2 }, + { .con_id = "osc_div4", .dt_id = TEGRA30_CLK_OSC_DIV4 }, { .con_id = "cml0", .dt_id = TEGRA30_CLK_CML0 }, { .con_id = "cml1", .dt_id = TEGRA30_CLK_CML1 }, { .con_id = "clk_m", .dt_id = TEGRA30_CLK_CLK_M }, @@ -683,8 +683,9 @@ static struct tegra_devclk devclks[] __initdata = { static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_clk_32k] = { .dt_id = TEGRA30_CLK_CLK_32K, .present = true }, [tegra_clk_clk_m] = { .dt_id = TEGRA30_CLK_CLK_M, .present = true }, - [tegra_clk_clk_m_div2] = { .dt_id = TEGRA30_CLK_CLK_M_DIV2, .present = true }, - [tegra_clk_clk_m_div4] = { .dt_id = TEGRA30_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_osc] = { .dt_id = TEGRA30_CLK_OSC, .present = true }, + [tegra_clk_osc_div2] = { .dt_id = TEGRA30_CLK_OSC_DIV2, .present = true }, + [tegra_clk_osc_div4] = { .dt_id = TEGRA30_CLK_OSC_DIV4, .present = true }, [tegra_clk_pll_ref] = { .dt_id = TEGRA30_CLK_PLL_REF, .present = true }, [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC, .present = true }, [tegra_clk_i2s0_sync] = { .dt_id = TEGRA30_CLK_I2S0_SYNC, .present = true }, @@ -711,13 +712,6 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_audio3_2x] = { .dt_id = TEGRA30_CLK_AUDIO3_2X, .present = true }, [tegra_clk_audio4_2x] = { .dt_id = TEGRA30_CLK_AUDIO4_2X, .present = true }, [tegra_clk_spdif_2x] = { .dt_id = TEGRA30_CLK_SPDIF_2X, .present = true }, - [tegra_clk_clk_out_1] = { .dt_id = TEGRA30_CLK_CLK_OUT_1, .present = true }, - [tegra_clk_clk_out_2] = { .dt_id = TEGRA30_CLK_CLK_OUT_2, .present = true }, - [tegra_clk_clk_out_3] = { .dt_id = TEGRA30_CLK_CLK_OUT_3, .present = true }, - [tegra_clk_blink] = { .dt_id = TEGRA30_CLK_BLINK, .present = true }, - [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_1_MUX, .present = true }, - [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_2_MUX, .present = true }, - [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_3_MUX, .present = true }, [tegra_clk_hclk] = { .dt_id = TEGRA30_CLK_HCLK, .present = true }, [tegra_clk_pclk] = { .dt_id = TEGRA30_CLK_PCLK, .present = true }, [tegra_clk_i2s0] = { .dt_id = TEGRA30_CLK_I2S0, .present = true }, @@ -1227,12 +1221,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0 }, { TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 408000000, 0 }, { TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 408000000, 0 }, - { TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 1 }, - { TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 1 }, - { TEGRA30_CLK_EXTERN1, TEGRA30_CLK_PLL_A_OUT0, 0, 1 }, - { TEGRA30_CLK_CLK_OUT_1_MUX, TEGRA30_CLK_EXTERN1, 0, 0 }, - { TEGRA30_CLK_CLK_OUT_1, TEGRA30_CLK_CLK_MAX, 0, 1 }, - { TEGRA30_CLK_BLINK, TEGRA30_CLK_CLK_MAX, 0, 1 }, + { TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 0 }, + { TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 0 }, { TEGRA30_CLK_I2S0, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA30_CLK_I2S1, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA30_CLK_I2S2, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 }, @@ -1362,7 +1352,6 @@ static void __init tegra30_clock_init(struct device_node *np) tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, tegra30_audio_plls, ARRAY_SIZE(tegra30_audio_plls), 24000000); - tegra_pmc_clk_init(pmc_base, tegra30_clks); tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 416a6b09f6a3..2c9a68302e02 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -854,7 +854,6 @@ void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, struct tegra_clk_pll_params *pll_params); -void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks); void tegra_fixed_clk_init(struct tegra_clk *tegra_clks); int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, unsigned long *input_freqs, unsigned int num, diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index fe686f77787f..692be2fd9261 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -34,18 +34,6 @@ #define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8) /** - * enum icst_control_type - the type of ICST control register - */ -enum icst_control_type { - ICST_VERSATILE, /* The standard type, all control bits available */ - ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */ - ICST_INTEGRATOR_AP_SYS, /* Only 8 bits of VDW available */ - ICST_INTEGRATOR_AP_PCI, /* Odd bit pattern storage */ - ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */ - ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */ -}; - -/** * struct clk_icst - ICST VCO clock wrapper * @hw: corresponding clock hardware entry * @vcoreg: VCO register address @@ -344,12 +332,12 @@ static const struct clk_ops icst_ops = { .set_rate = icst_set_rate, }; -static struct clk *icst_clk_setup(struct device *dev, - const struct clk_icst_desc *desc, - const char *name, - const char *parent_name, - struct regmap *map, - enum icst_control_type ctype) +struct clk *icst_clk_setup(struct device *dev, + const struct clk_icst_desc *desc, + const char *name, + const char *parent_name, + struct regmap *map, + enum icst_control_type ctype) { struct clk *clk; struct clk_icst *icst; @@ -386,6 +374,7 @@ static struct clk *icst_clk_setup(struct device *dev, return clk; } +EXPORT_SYMBOL_GPL(icst_clk_setup); struct clk *icst_clk_register(struct device *dev, const struct clk_icst_desc *desc, diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h index e36ca1a20e90..1a119ef11066 100644 --- a/drivers/clk/versatile/clk-icst.h +++ b/drivers/clk/versatile/clk-icst.h @@ -1,4 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0 */ +struct regmap; + +/** + * enum icst_control_type - the type of ICST control register + */ +enum icst_control_type { + ICST_VERSATILE, /* The standard type, all control bits available */ + ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */ + ICST_INTEGRATOR_AP_SYS, /* Only 8 bits of VDW available */ + ICST_INTEGRATOR_AP_PCI, /* Odd bit pattern storage */ + ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */ + ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */ + ICST_INTEGRATOR_IM_PD1, /* Like the Versatile, all control bits */ +}; + /** * struct clk_icst_desc - descriptor for the ICST VCO * @params: ICST parameters @@ -17,3 +32,10 @@ struct clk *icst_clk_register(struct device *dev, const char *name, const char *parent_name, void __iomem *base); + +struct clk *icst_clk_setup(struct device *dev, + const struct clk_icst_desc *desc, + const char *name, + const char *parent_name, + struct regmap *map, + enum icst_control_type ctype); diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 1991f15a5db9..b05da8516d4c 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c @@ -7,7 +7,11 @@ #include <linux/clkdev.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/platform_device.h> #include <linux/platform_data/clk-integrator.h> +#include <linux/module.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> #include "icst.h" #include "clk-icst.h" @@ -175,3 +179,78 @@ void integrator_impd1_clk_exit(unsigned int id) kfree(imc->pclkname); } EXPORT_SYMBOL_GPL(integrator_impd1_clk_exit); + +static int integrator_impd1_clk_spawn(struct device *dev, + struct device_node *parent, + struct device_node *np) +{ + struct regmap *map; + struct clk *clk = ERR_PTR(-EINVAL); + const char *name = np->name; + const char *parent_name; + const struct clk_icst_desc *desc; + int ret; + + map = syscon_node_to_regmap(parent); + if (IS_ERR(map)) { + pr_err("no regmap for syscon IM-PD1 ICST clock parent\n"); + return PTR_ERR(map); + } + + if (of_device_is_compatible(np, "arm,impd1-vco1")) { + desc = &impd1_icst1_desc; + } else if (of_device_is_compatible(np, "arm,impd1-vco2")) { + desc = &impd1_icst2_desc; + } else { + dev_err(dev, "not a clock node %s\n", name); + return -ENODEV; + } + + parent_name = of_clk_get_parent_name(np, 0); + clk = icst_clk_setup(NULL, desc, name, parent_name, map, + ICST_INTEGRATOR_IM_PD1); + if (!IS_ERR(clk)) { + of_clk_add_provider(np, of_clk_src_simple_get, clk); + ret = 0; + } else { + dev_err(dev, "error setting up IM-PD1 ICST clock\n"); + ret = PTR_ERR(clk); + } + + return ret; +} + +static int integrator_impd1_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *child; + int ret = 0; + + for_each_available_child_of_node(np, child) { + ret = integrator_impd1_clk_spawn(dev, np, child); + if (ret) + break; + } + + return ret; +} + +static const struct of_device_id impd1_syscon_match[] = { + { .compatible = "arm,im-pd1-syscon", }, + {} +}; +MODULE_DEVICE_TABLE(of, impd1_syscon_match); + +static struct platform_driver impd1_clk_driver = { + .driver = { + .name = "impd1-clk", + .of_match_table = impd1_syscon_match, + }, + .probe = integrator_impd1_clk_probe, +}; +builtin_platform_driver(impd1_clk_driver); + +MODULE_AUTHOR("Linus Walleij <linusw@kernel.org>"); +MODULE_DESCRIPTION("Arm IM-PD1 module clock driver"); +MODULE_LICENSE("GPL v2"); |