diff options
74 files changed, 4368 insertions, 624 deletions
diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt index 8968371d84e2..888c50e0d64f 100644 --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt @@ -7,6 +7,14 @@ registers giving access to numerous features: clocks, pin-muxing and many other SoC configuration items. This DT binding allows to describe this system controller. +For the top level node: + - compatible: must be: "syscon", "simple-mfd"; + - reg: register area of the AP806 system controller + +Clocks: +------- + + The Device Tree node representing the AP806 system controller provides a number of clocks: @@ -17,19 +25,17 @@ a number of clocks: Required properties: - - compatible: must be: - "marvell,ap806-system-controller", "syscon" - - reg: register area of the AP806 system controller + - compatible: must be: "marvell,ap806-clock" - #clock-cells: must be set to 1 - - clock-output-names: must be defined to: - "ap-cpu-cluster-0", "ap-cpu-cluster-1", "ap-fixed", "ap-mss" Example: syscon: system-controller@6f4000 { - compatible = "marvell,ap806-system-controller", "syscon"; - #clock-cells = <1>; - clock-output-names = "ap-cpu-cluster-0", "ap-cpu-cluster-1", - "ap-fixed", "ap-mss"; + compatible = "syscon", "simple-mfd"; reg = <0x6f4000 0x1000>; + + ap_clk: clock { + compatible = "marvell,ap806-clock"; + #clock-cells = <1>; + }; }; diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt index 6ed469c66b32..6498e1fdbb33 100644 --- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt +++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt @@ -57,6 +57,11 @@ Optional properties: - clocks: If clock-frequency is not specified, sysclk may be provided as an input clock. Either clock-frequency or clocks must be provided. + A second input clock, called "coreclk", may be provided if + core PLLs are based on a different input clock from the + platform PLL. +- clock-names: Required if a coreclk is present. Valid names are + "sysclk" and "coreclk". 2. Clock Provider @@ -73,6 +78,7 @@ second cell is the clock index for the specified type. 2 hwaccel index (n in CLKCGnHWACSR) 3 fman 0 for fm1, 1 for fm2 4 platform pll 0=pll, 1=pll/2, 2=pll/3, 3=pll/4 + 5 coreclk must be 0 3. Example diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index f4f944d81308..0cd894f987a3 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -15,6 +15,11 @@ Required Properties: - compatible: Must be one of: - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) + - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) + - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) + - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H) + - "renesas,r8a7793-cpg-mssr" for the r8a7793 SoC (R-Car M2-N) + - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) @@ -24,9 +29,10 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a7795, r8a7796) + - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, + r8a7795, r8a7796) - "extalr" (r8a7795, r8a7796) - - "usb_extal" (r8a7743, r8a7745) + - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) - #clock-cells: Must be 2 - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt new file mode 100644 index 000000000000..455a9a00a623 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt @@ -0,0 +1,56 @@ +* Rockchip RK3128 Clock and Reset Unit + +The RK3128 clock controller generates and supplies clock to various +controllers within the SoC and also implements a reset controller for SoC +peripherals. + +Required Properties: + +- compatible: should be "rockchip,rk3128-cru" +- reg: physical base address of the controller and length of memory mapped + region. +- #clock-cells: should be 1. +- #reset-cells: should be 1. + +Optional Properties: + +- rockchip,grf: phandle to the syscon managing the "general register files" + If missing pll rates are not changeable, due to the missing pll lock status. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/rk3128-cru.h headers and can be +used in device tree sources. Similar macros exist for the reset sources in +these files. + +External clocks: + +There are several clocks that are generated outside the SoC. It is expected +that they are defined using standard clock bindings with following +clock-output-names: + - "xin24m" - crystal input - required, + - "ext_i2s" - external I2S clock - optional, + - "gmac_clkin" - external GMAC clock - optional + +Example: Clock controller node: + + cru: cru@20000000 { + compatible = "rockchip,rk3128-cru"; + reg = <0x20000000 0x1000>; + rockchip,grf = <&grf>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart2: serial@20068000 { + compatible = "rockchip,serial"; + reg = <0x20068000 0x100>; + interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <24000000>; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "sclk_uart", "pclk_uart"; + }; diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt new file mode 100644 index 000000000000..1e884c40ab50 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt @@ -0,0 +1,37 @@ +Texas Instruments TI-SCI Clocks +=============================== + +All clocks on Texas Instruments' SoCs that contain a System Controller, +are only controlled by this entity. Communication between a host processor +running an OS and the System Controller happens through a protocol known +as TI-SCI[1]. This clock implementation plugs into the common clock +framework and makes use of the TI-SCI protocol on clock API requests. + +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt + +Required properties: +------------------- +- compatible: Must be "ti,k2g-sci-clk" +- #clock-cells: Shall be 2. + In clock consumers, this cell represents the device ID and clock ID + exposed by the PM firmware. The assignments can be found in the header + files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and + <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc> + is the SoC involved, for example 'k2g'. + +Examples: +-------- + +pmmc: pmmc { + compatible = "ti,k2g-sci"; + + k2g_clks: clocks { + compatible = "ti,k2g-sci-clk"; + #clock-cells = <2>; + }; +}; + +uart0: serial@2530c00 { + compatible = "ns16550a"; + clocks = <&k2g_clks 0x2c 0>; +}; diff --git a/MAINTAINERS b/MAINTAINERS index f7d568b8f133..1ba72e6d8254 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12630,6 +12630,8 @@ F: include/linux/soc/ti/ti_sci_protocol.h F: Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt F: include/dt-bindings/genpd/k2g.h F: drivers/soc/ti/ti_sci_pm_domains.c +F: Documentation/devicetree/bindings/clock/ti,sci-clk.txt +F: drivers/clk/keystone/sci-clk.c THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER M: Hans Verkuil <hverkuil@xs4all.nl> diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index 149f0513c4f5..a263d1b751ff 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c @@ -160,11 +160,6 @@ void clk_deactivate(struct clk *clk) } EXPORT_SYMBOL(clk_deactivate); -struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) -{ - return NULL; -} - static inline u32 get_counter_resolution(void) { u32 res; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 36cfea38135f..10fef771bb36 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -164,13 +164,6 @@ config COMMON_CLK_XGENE ---help--- Sypport for the APM X-Gene SoC reference, PLL, and device clocks. -config COMMON_CLK_KEYSTONE - tristate "Clock drivers for Keystone based SOCs" - depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF - ---help--- - Supports clock drivers for Keystone based SOCs. These SOCs have local - a power sleep control module that gate the clock to the IPs and PLLs. - config COMMON_CLK_NXP def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX) select REGMAP_MMIO if ARCH_LPC32XX @@ -219,6 +212,7 @@ config COMMON_CLK_VC5 source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" +source "drivers/clk/keystone/Kconfig" source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index c19983afcb81..de99e600711d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -1,5 +1,5 @@ # common clock types -obj-$(CONFIG_HAVE_CLK) += clk-devres.o +obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o obj-$(CONFIG_COMMON_CLK) += clk.o obj-$(CONFIG_COMMON_CLK) += clk-divider.o @@ -61,7 +61,7 @@ obj-$(CONFIG_H8300) += h8300/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-$(CONFIG_ARCH_MXC) += imx/ obj-$(CONFIG_MACH_INGENIC) += ingenic/ -obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ +obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(CONFIG_MACH_LOONGSON32) += loongson1/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/ @@ -75,7 +75,7 @@ obj-$(CONFIG_COMMON_CLK_NXP) += nxp/ obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ -obj-$(CONFIG_ARCH_RENESAS) += renesas/ +obj-y += renesas/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ obj-$(CONFIG_ARCH_SIRF) += sirf/ diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 4e1cd5aa69d8..07c8f701e51c 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -260,13 +260,13 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, gck->lock = lock; gck->range = *range; + clk_generated_startup(gck); hw = &gck->hw; ret = clk_hw_register(NULL, &gck->hw); if (ret) { kfree(gck); hw = ERR_PTR(ret); - } else - clk_generated_startup(gck); + } return hw; } diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 025853870619..58ce6af8452d 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -530,6 +530,7 @@ struct bcm2835_clock_data { bool is_vpu_clock; bool is_mash_clock; + bool low_jitter; u32 tcnt_mux; }; @@ -616,8 +617,10 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & data->ana->fb_prediv_mask; - if (using_prediv) + if (using_prediv) { ndiv *= 2; + fdiv *= 2; + } return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv); } @@ -1124,7 +1127,8 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, int parent_idx, unsigned long rate, u32 *div, - unsigned long *prate) + unsigned long *prate, + unsigned long *avgrate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; @@ -1139,8 +1143,25 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, *prate = clk_hw_get_rate(parent); *div = bcm2835_clock_choose_div(hw, rate, *prate, true); - return bcm2835_clock_rate_from_divisor(clock, *prate, - *div); + *avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div); + + if (data->low_jitter && (*div & CM_DIV_FRAC_MASK)) { + unsigned long high, low; + u32 int_div = *div & ~CM_DIV_FRAC_MASK; + + high = bcm2835_clock_rate_from_divisor(clock, *prate, + int_div); + int_div += CM_DIV_FRAC_MASK + 1; + low = bcm2835_clock_rate_from_divisor(clock, *prate, + int_div); + + /* + * Return a value which is the maximum deviation + * below the ideal rate, for use as a metric. + */ + return *avgrate - max(*avgrate - low, high - *avgrate); + } + return *avgrate; } if (data->frac_bits) @@ -1167,6 +1188,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, *div = curdiv << CM_DIV_FRAC_BITS; *prate = curdiv * best_rate; + *avgrate = best_rate; return best_rate; } @@ -1178,6 +1200,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, bool current_parent_is_pllc; unsigned long rate, best_rate = 0; unsigned long prate, best_prate = 0; + unsigned long avgrate, best_avgrate = 0; size_t i; u32 div; @@ -1202,11 +1225,13 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, continue; rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, - &div, &prate); + &div, &prate, + &avgrate); if (rate > best_rate && rate <= req->rate) { best_parent = parent; best_prate = prate; best_rate = rate; + best_avgrate = avgrate; } } @@ -1216,7 +1241,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, req->best_parent_hw = best_parent; req->best_parent_rate = best_prate; - req->rate = best_rate; + req->rate = best_avgrate; return 0; } @@ -1516,6 +1541,31 @@ static const char *const bcm2835_clock_per_parents[] = { .parents = bcm2835_clock_per_parents, \ __VA_ARGS__) +/* + * Restrict clock sources for the PCM peripheral to the oscillator and + * PLLD_PER because other source may have varying rates or be switched + * off. + * + * Prevent other sources from being selected by replacing their names in + * the list of potential parents with dummy entries (entry index is + * significant). + */ +static const char *const bcm2835_pcm_per_parents[] = { + "-", + "xosc", + "-", + "-", + "-", + "-", + "plld_per", + "-", +}; + +#define REGISTER_PCM_CLK(...) REGISTER_CLK( \ + .num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents), \ + .parents = bcm2835_pcm_per_parents, \ + __VA_ARGS__) + /* main vpu parent mux */ static const char *const bcm2835_clock_vpu_parents[] = { "gnd", @@ -1993,13 +2043,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .int_bits = 4, .frac_bits = 8, .tcnt_mux = 22), - [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( + [BCM2835_CLOCK_PCM] = REGISTER_PCM_CLK( .name = "pcm", .ctl_reg = CM_PCMCTL, .div_reg = CM_PCMDIV, .int_bits = 12, .frac_bits = 12, .is_mash_clock = true, + .low_jitter = true, .tcnt_mux = 23), [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( .name = "pwm", diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c new file mode 100644 index 000000000000..c834f5abfc49 --- /dev/null +++ b/drivers/clk/clk-bulk.c @@ -0,0 +1,157 @@ +/* + * Copyright 2017 NXP + * + * Dong Aisheng <aisheng.dong@nxp.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/export.h> + +void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) +{ + while (--num_clks >= 0) { + clk_put(clks[num_clks].clk); + clks[num_clks].clk = NULL; + } +} +EXPORT_SYMBOL_GPL(clk_bulk_put); + +int __must_check clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + int ret; + int i; + + for (i = 0; i < num_clks; i++) + clks[i].clk = NULL; + + for (i = 0; i < num_clks; i++) { + clks[i].clk = clk_get(dev, clks[i].id); + if (IS_ERR(clks[i].clk)) { + ret = PTR_ERR(clks[i].clk); + dev_err(dev, "Failed to get clk '%s': %d\n", + clks[i].id, ret); + clks[i].clk = NULL; + goto err; + } + } + + return 0; + +err: + clk_bulk_put(i, clks); + + return ret; +} +EXPORT_SYMBOL(clk_bulk_get); + +#ifdef CONFIG_HAVE_CLK_PREPARE + +/** + * clk_bulk_unprepare - undo preparation of a set of clock sources + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being unprepared + * + * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable. + * Returns 0 on success, -EERROR otherwise. + */ +void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks) +{ + while (--num_clks >= 0) + clk_unprepare(clks[num_clks].clk); +} +EXPORT_SYMBOL_GPL(clk_bulk_unprepare); + +/** + * clk_bulk_prepare - prepare a set of clocks + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being prepared + * + * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable. + * Returns 0 on success, -EERROR otherwise. + */ +int __must_check clk_bulk_prepare(int num_clks, + const struct clk_bulk_data *clks) +{ + int ret; + int i; + + for (i = 0; i < num_clks; i++) { + ret = clk_prepare(clks[i].clk); + if (ret) { + pr_err("Failed to prepare clk '%s': %d\n", + clks[i].id, ret); + goto err; + } + } + + return 0; + +err: + clk_bulk_unprepare(i, clks); + + return ret; +} + +#endif /* CONFIG_HAVE_CLK_PREPARE */ + +/** + * clk_bulk_disable - gate a set of clocks + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being gated + * + * clk_bulk_disable must not sleep, which differentiates it from + * clk_bulk_unprepare. clk_bulk_disable must be called before + * clk_bulk_unprepare. + */ +void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks) +{ + + while (--num_clks >= 0) + clk_disable(clks[num_clks].clk); +} +EXPORT_SYMBOL_GPL(clk_bulk_disable); + +/** + * clk_bulk_enable - ungate a set of clocks + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being ungated + * + * clk_bulk_enable must not sleep + * Returns 0 on success, -EERROR otherwise. + */ +int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks) +{ + int ret; + int i; + + for (i = 0; i < num_clks; i++) { + ret = clk_enable(clks[i].clk); + if (ret) { + pr_err("Failed to enable clk '%s': %d\n", + clks[i].id, ret); + goto err; + } + } + + return 0; + +err: + clk_bulk_disable(i, clks); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_bulk_enable); diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index e0e02a6e5900..7ec36722f8ab 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -109,7 +109,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) rc = clk_set_rate(clk, rate); if (rc < 0) - pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n", + pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n", __clk_get_name(clk), rate, rc, clk_get_rate(clk)); clk_put(clk); diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index 3a218c3a06ae..d854e26a8ddb 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c @@ -34,6 +34,42 @@ struct clk *devm_clk_get(struct device *dev, const char *id) } EXPORT_SYMBOL(devm_clk_get); +struct clk_bulk_devres { + struct clk_bulk_data *clks; + int num_clks; +}; + +static void devm_clk_bulk_release(struct device *dev, void *res) +{ + struct clk_bulk_devres *devres = res; + + clk_bulk_put(devres->num_clks, devres->clks); +} + +int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + struct clk_bulk_devres *devres; + int ret; + + devres = devres_alloc(devm_clk_bulk_release, + sizeof(*devres), GFP_KERNEL); + if (!devres) + return -ENOMEM; + + ret = clk_bulk_get(dev, num_clks, clks); + if (!ret) { + devres->clks = clks; + devres->num_clks = num_clks; + devres_add(dev, devres); + } else { + devres_free(devres); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_clk_bulk_get); + static int devm_clk_match(struct device *dev, void *res, void *data) { struct clk **c = res; diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 31f590cea493..7f51c01085ab 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -229,6 +229,7 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo) if (ret < 0) { dev_err(cinfo->dev, "Ext config for %s failed, %d\n", cinfo->clk_desc->clk_name, ret); + clk_unprepare(cinfo->hw.clk); return ret; } } diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index d0bf8b1c67de..f3931e38fac0 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -87,7 +87,7 @@ struct clockgen { struct device_node *node; void __iomem *regs; struct clockgen_chipinfo info; /* mutable copy */ - struct clk *sysclk; + struct clk *sysclk, *coreclk; struct clockgen_pll pll[6]; struct clk *cmux[NUM_CMUX]; struct clk *hwaccel[NUM_HWACCEL]; @@ -904,7 +904,12 @@ static void __init create_muxes(struct clockgen *cg) static void __init clockgen_init(struct device_node *np); -/* Legacy nodes may get probed before the parent clockgen node */ +/* + * Legacy nodes may get probed before the parent clockgen node. + * It is assumed that device trees with legacy nodes will not + * contain a "clocks" property -- otherwise the input clocks may + * not be initialized at this point. + */ static void __init legacy_init_clockgen(struct device_node *np) { if (!clockgen.node) @@ -945,18 +950,13 @@ static struct clk __init return clk_register_fixed_rate(NULL, name, NULL, 0, rate); } -static struct clk *sysclk_from_parent(const char *name) +static struct clk __init *input_clock(const char *name, struct clk *clk) { - struct clk *clk; - const char *parent_name; - - clk = of_clk_get(clockgen.node, 0); - if (IS_ERR(clk)) - return clk; + const char *input_name; /* Register the input clock under the desired name. */ - parent_name = __clk_get_name(clk); - clk = clk_register_fixed_factor(NULL, name, parent_name, + input_name = __clk_get_name(clk); + clk = clk_register_fixed_factor(NULL, name, input_name, 0, 1, 1); if (IS_ERR(clk)) pr_err("%s: Couldn't register %s: %ld\n", __func__, name, @@ -965,6 +965,29 @@ static struct clk *sysclk_from_parent(const char *name) return clk; } +static struct clk __init *input_clock_by_name(const char *name, + const char *dtname) +{ + struct clk *clk; + + clk = of_clk_get_by_name(clockgen.node, dtname); + if (IS_ERR(clk)) + return clk; + + return input_clock(name, clk); +} + +static struct clk __init *input_clock_by_index(const char *name, int idx) +{ + struct clk *clk; + + clk = of_clk_get(clockgen.node, 0); + if (IS_ERR(clk)) + return clk; + + return input_clock(name, clk); +} + static struct clk * __init create_sysclk(const char *name) { struct device_node *sysclk; @@ -974,7 +997,11 @@ static struct clk * __init create_sysclk(const char *name) if (!IS_ERR(clk)) return clk; - clk = sysclk_from_parent(name); + clk = input_clock_by_name(name, "sysclk"); + if (!IS_ERR(clk)) + return clk; + + clk = input_clock_by_index(name, 0); if (!IS_ERR(clk)) return clk; @@ -985,7 +1012,27 @@ static struct clk * __init create_sysclk(const char *name) return clk; } - pr_err("%s: No input clock\n", __func__); + pr_err("%s: No input sysclk\n", __func__); + return NULL; +} + +static struct clk * __init create_coreclk(const char *name) +{ + struct clk *clk; + + clk = input_clock_by_name(name, "coreclk"); + if (!IS_ERR(clk)) + return clk; + + /* + * This indicates a mix of legacy nodes with the new coreclk + * mechanism, which should never happen. If this error occurs, + * don't use the wrong input clock just because coreclk isn't + * ready yet. + */ + if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER)) + return clk; + return NULL; } @@ -1008,11 +1055,19 @@ static void __init create_one_pll(struct clockgen *cg, int idx) u32 __iomem *reg; u32 mult; struct clockgen_pll *pll = &cg->pll[idx]; + const char *input = "cg-sysclk"; int i; if (!(cg->info.pll_mask & (1 << idx))) return; + if (cg->coreclk && idx != PLATFORM_PLL) { + if (IS_ERR(cg->coreclk)) + return; + + input = "cg-coreclk"; + } + if (cg->info.flags & CG_VER3) { switch (idx) { case PLATFORM_PLL: @@ -1063,7 +1118,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx) "cg-pll%d-div%d", idx, i + 1); clk = clk_register_fixed_factor(NULL, - pll->div[i].name, "cg-sysclk", 0, mult, i + 1); + pll->div[i].name, input, 0, mult, i + 1); if (IS_ERR(clk)) { pr_err("%s: %s: register failed %ld\n", __func__, pll->div[i].name, PTR_ERR(clk)); @@ -1200,6 +1255,13 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data) goto bad_args; clk = pll->div[idx].clk; break; + case 5: + if (idx != 0) + goto bad_args; + clk = cg->coreclk; + if (IS_ERR(clk)) + clk = NULL; + break; default: goto bad_args; } @@ -1311,6 +1373,7 @@ static void __init clockgen_init(struct device_node *np) clockgen.info.flags |= CG_CMUX_GE_PLAT; clockgen.sysclk = create_sysclk("cg-sysclk"); + clockgen.coreclk = create_coreclk("cg-coreclk"); create_plls(&clockgen); create_muxes(&clockgen); diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 96d37175d0ad..8ad458b5ad6e 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -71,15 +71,15 @@ static const struct clk_ops scpi_clk_ops = { }; /* find closest match to given frequency in OPP table */ -static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate) +static long __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate) { int idx; - u32 fmin = 0, fmax = ~0, ftmp; + unsigned long fmin = 0, fmax = ~0, ftmp; const struct scpi_opp *opp = clk->info->opps; for (idx = 0; idx < clk->info->count; idx++, opp++) { ftmp = opp->freq; - if (ftmp >= (u32)rate) { + if (ftmp >= rate) { if (ftmp <= fmax) fmax = ftmp; break; diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 93b03640da9b..8fa1841b15df 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -424,7 +424,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "osc", base + 0x60, 0x7f); - clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_dram_main", "osc", base + 0x70, 0x7f); + clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f); clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1); clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0); clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "osc", base + 0xf0, 0x7f); diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index f1099167ba31..9af62ee8f347 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -27,6 +27,7 @@ #define BM_PLL_POWER (0x1 << 12) #define BM_PLL_LOCK (0x1 << 31) #define IMX7_ENET_PLL_POWER (0x1 << 5) +#define IMX7_DDR_PLL_POWER (0x1 << 20) /** * struct clk_pllv3 - IMX PLL clock version 3 @@ -451,6 +452,10 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, pll->ref_clock = 500000000; ops = &clk_pllv3_enet_ops; break; + case IMX_PLLV3_DDR_IMX7: + pll->power_bit = IMX7_DDR_PLL_POWER; + ops = &clk_pllv3_av_ops; + break; default: ops = &clk_pllv3_ops; } diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index e1f5e425db73..d54f0720afba 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -35,6 +35,7 @@ enum imx_pllv3_type { IMX_PLLV3_ENET, IMX_PLLV3_ENET_IMX7, IMX_PLLV3_SYS_VF610, + IMX_PLLV3_DDR_IMX7, }; struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig new file mode 100644 index 000000000000..1fea328a36fe --- /dev/null +++ b/drivers/clk/keystone/Kconfig @@ -0,0 +1,15 @@ +config COMMON_CLK_KEYSTONE + tristate "Clock drivers for Keystone based SOCs" + depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF + ---help--- + Supports clock drivers for Keystone based SOCs. These SOCs have local + a power sleep control module that gate the clock to the IPs and PLLs. + +config TI_SCI_CLK + tristate "TI System Control Interface clock drivers" + depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF + default TI_SCI_PROTOCOL + ---help--- + This adds the clock driver support over TI System Control Interface. + If you wish to use clock resources from the PMMC firmware, say Y. + Otherwise, say N. diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile index 0477cf63f132..c12593966f9b 100644 --- a/drivers/clk/keystone/Makefile +++ b/drivers/clk/keystone/Makefile @@ -1 +1,2 @@ -obj-y += pll.o gate.o +obj-$(CONFIG_COMMON_CLK_KEYSTONE) += pll.o gate.o +obj-$(CONFIG_TI_SCI_CLK) += sci-clk.o diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c new file mode 100644 index 000000000000..43b0f2f08df2 --- /dev/null +++ b/drivers/clk/keystone/sci-clk.c @@ -0,0 +1,724 @@ +/* + * SCI Clock driver for keystone based devices + * + * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ + * Tero Kristo <t-kristo@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/soc/ti/ti_sci_protocol.h> + +#define SCI_CLK_SSC_ENABLE BIT(0) +#define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1) +#define SCI_CLK_INPUT_TERMINATION BIT(2) + +/** + * struct sci_clk_data - TI SCI clock data + * @dev: device index + * @num_clks: number of clocks for this device + */ +struct sci_clk_data { + u16 dev; + u16 num_clks; +}; + +/** + * struct sci_clk_provider - TI SCI clock provider representation + * @sci: Handle to the System Control Interface protocol handler + * @ops: Pointer to the SCI ops to be used by the clocks + * @dev: Device pointer for the clock provider + * @clk_data: Clock data + * @clocks: Clocks array for this device + */ +struct sci_clk_provider { + const struct ti_sci_handle *sci; + const struct ti_sci_clk_ops *ops; + struct device *dev; + const struct sci_clk_data *clk_data; + struct clk_hw **clocks; +}; + +/** + * struct sci_clk - TI SCI clock representation + * @hw: Hardware clock cookie for common clock framework + * @dev_id: Device index + * @clk_id: Clock index + * @node: Clocks list link + * @provider: Master clock provider + * @flags: Flags for the clock + */ +struct sci_clk { + struct clk_hw hw; + u16 dev_id; + u8 clk_id; + struct list_head node; + struct sci_clk_provider *provider; + u8 flags; +}; + +#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw) + +/** + * sci_clk_prepare - Prepare (enable) a TI SCI clock + * @hw: clock to prepare + * + * Prepares a clock to be actively used. Returns the SCI protocol status. + */ +static int sci_clk_prepare(struct clk_hw *hw) +{ + struct sci_clk *clk = to_sci_clk(hw); + bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE; + bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE; + bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION; + + return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id, + clk->clk_id, enable_ssc, + allow_freq_change, + input_termination); +} + +/** + * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock + * @hw: clock to unprepare + * + * Un-prepares a clock from active state. + */ +static void sci_clk_unprepare(struct clk_hw *hw) +{ + struct sci_clk *clk = to_sci_clk(hw); + int ret; + + ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id, + clk->clk_id); + if (ret) + dev_err(clk->provider->dev, + "unprepare failed for dev=%d, clk=%d, ret=%d\n", + clk->dev_id, clk->clk_id, ret); +} + +/** + * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not + * @hw: clock to check status for + * + * Checks if a clock is prepared (enabled) in hardware. Returns non-zero + * value if clock is enabled, zero otherwise. + */ +static int sci_clk_is_prepared(struct clk_hw *hw) +{ + struct sci_clk *clk = to_sci_clk(hw); + bool req_state, current_state; + int ret; + + ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id, + clk->clk_id, &req_state, + ¤t_state); + if (ret) { + dev_err(clk->provider->dev, + "is_prepared failed for dev=%d, clk=%d, ret=%d\n", + clk->dev_id, clk->clk_id, ret); + return 0; + } + + return req_state; +} + +/** + * sci_clk_recalc_rate - Get clock rate for a TI SCI clock + * @hw: clock to get rate for + * @parent_rate: parent rate provided by common clock framework, not used + * + * Gets the current clock rate of a TI SCI clock. Returns the current + * clock rate, or zero in failure. + */ +static unsigned long sci_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sci_clk *clk = to_sci_clk(hw); + u64 freq; + int ret; + + ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id, + clk->clk_id, &freq); + if (ret) { + dev_err(clk->provider->dev, + "recalc-rate failed for dev=%d, clk=%d, ret=%d\n", + clk->dev_id, clk->clk_id, ret); + return 0; + } + + return freq; +} + +/** + * sci_clk_determine_rate - Determines a clock rate a clock can be set to + * @hw: clock to change rate for + * @req: requested rate configuration for the clock + * + * Determines a suitable clock rate and parent for a TI SCI clock. + * The parent handling is un-used, as generally the parent clock rates + * are not known by the kernel; instead these are internally handled + * by the firmware. Returns 0 on success, negative error value on failure. + */ +static int sci_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct sci_clk *clk = to_sci_clk(hw); + int ret; + u64 new_rate; + + ret = clk->provider->ops->get_best_match_freq(clk->provider->sci, + clk->dev_id, + clk->clk_id, + req->min_rate, + req->rate, + req->max_rate, + &new_rate); + if (ret) { + dev_err(clk->provider->dev, + "determine-rate failed for dev=%d, clk=%d, ret=%d\n", + clk->dev_id, clk->clk_id, ret); + return ret; + } + + req->rate = new_rate; + + return 0; +} + +/** + * sci_clk_set_rate - Set rate for a TI SCI clock + * @hw: clock to change rate for + * @rate: target rate for the clock + * @parent_rate: rate of the clock parent, not used for TI SCI clocks + * + * Sets a clock frequency for a TI SCI clock. Returns the TI SCI + * protocol status. + */ +static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sci_clk *clk = to_sci_clk(hw); + + return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, + clk->clk_id, rate, rate, rate); +} + +/** + * sci_clk_get_parent - Get the current parent of a TI SCI clock + * @hw: clock to get parent for + * + * Returns the index of the currently selected parent for a TI SCI clock. + */ +static u8 sci_clk_get_parent(struct clk_hw *hw) +{ + struct sci_clk *clk = to_sci_clk(hw); + u8 parent_id; + int ret; + + ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id, + clk->clk_id, &parent_id); + if (ret) { + dev_err(clk->provider->dev, + "get-parent failed for dev=%d, clk=%d, ret=%d\n", + clk->dev_id, clk->clk_id, ret); + return 0; + } + + return parent_id - clk->clk_id - 1; +} + +/** + * sci_clk_set_parent - Set the parent of a TI SCI clock + * @hw: clock to set parent for + * @index: new parent index for the clock + * + * Sets the parent of a TI SCI clock. Return TI SCI protocol status. + */ +static int sci_clk_set_parent(struct clk_hw *hw, u8 index) +{ + struct sci_clk *clk = to_sci_clk(hw); + + return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, + clk->clk_id, + index + 1 + clk->clk_id); +} + +static const struct clk_ops sci_clk_ops = { + .prepare = sci_clk_prepare, + .unprepare = sci_clk_unprepare, + .is_prepared = sci_clk_is_prepared, + .recalc_rate = sci_clk_recalc_rate, + .determine_rate = sci_clk_determine_rate, + .set_rate = sci_clk_set_rate, + .get_parent = sci_clk_get_parent, + .set_parent = sci_clk_set_parent, +}; + +/** + * _sci_clk_get - Gets a handle for an SCI clock + * @provider: Handle to SCI clock provider + * @dev_id: device ID for the clock to register + * @clk_id: clock ID for the clock to register + * + * Gets a handle to an existing TI SCI hw clock, or builds a new clock + * entry and registers it with the common clock framework. Called from + * the common clock framework, when a corresponding of_clk_get call is + * executed, or recursively from itself when parsing parent clocks. + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure. + */ +static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider, + u16 dev_id, u8 clk_id) +{ + struct clk_init_data init = { NULL }; + struct sci_clk *sci_clk = NULL; + char *name = NULL; + char **parent_names = NULL; + int i; + int ret; + + sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL); + if (!sci_clk) + return ERR_PTR(-ENOMEM); + + sci_clk->dev_id = dev_id; + sci_clk->clk_id = clk_id; + sci_clk->provider = provider; + + ret = provider->ops->get_num_parents(provider->sci, dev_id, + clk_id, + &init.num_parents); + if (ret) + goto err; + + name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev), + sci_clk->dev_id, sci_clk->clk_id); + + init.name = name; + + /* + * From kernel point of view, we only care about a clocks parents, + * if it has more than 1 possible parent. In this case, it is going + * to have mux functionality. Otherwise it is going to act as a root + * clock. + */ + if (init.num_parents < 2) + init.num_parents = 0; + + if (init.num_parents) { + parent_names = kcalloc(init.num_parents, sizeof(char *), + GFP_KERNEL); + + if (!parent_names) { + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < init.num_parents; i++) { + char *parent_name; + + parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d", + dev_name(provider->dev), + sci_clk->dev_id, + sci_clk->clk_id + 1 + i); + if (!parent_name) { + ret = -ENOMEM; + goto err; + } + parent_names[i] = parent_name; + } + init.parent_names = (void *)parent_names; + } + + init.ops = &sci_clk_ops; + sci_clk->hw.init = &init; + + ret = devm_clk_hw_register(provider->dev, &sci_clk->hw); + if (ret) + dev_err(provider->dev, "failed clk register with %d\n", ret); + +err: + if (parent_names) { + for (i = 0; i < init.num_parents; i++) + kfree(parent_names[i]); + + kfree(parent_names); + } + + kfree(name); + + if (ret) + return ERR_PTR(ret); + + return &sci_clk->hw; +} + +/** + * sci_clk_get - Xlate function for getting clock handles + * @clkspec: device tree clock specifier + * @data: pointer to the clock provider + * + * Xlate function for retrieving clock TI SCI hw clock handles based on + * device tree clock specifier. Called from the common clock framework, + * when a corresponding of_clk_get call is executed. Returns a pointer + * to the TI SCI hw clock struct, or ERR_PTR value in failure. + */ +static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data) +{ + struct sci_clk_provider *provider = data; + u16 dev_id; + u8 clk_id; + const struct sci_clk_data *clks = provider->clk_data; + struct clk_hw **clocks = provider->clocks; + + if (clkspec->args_count != 2) + return ERR_PTR(-EINVAL); + + dev_id = clkspec->args[0]; + clk_id = clkspec->args[1]; + + while (clks->num_clks) { + if (clks->dev == dev_id) { + if (clk_id >= clks->num_clks) + return ERR_PTR(-EINVAL); + + return clocks[clk_id]; + } + + clks++; + } + + return ERR_PTR(-ENODEV); +} + +static int ti_sci_init_clocks(struct sci_clk_provider *p) +{ + const struct sci_clk_data *data = p->clk_data; + struct clk_hw *hw; + int i; + + while (data->num_clks) { + p->clocks = devm_kcalloc(p->dev, data->num_clks, + sizeof(struct sci_clk), + GFP_KERNEL); + if (!p->clocks) + return -ENOMEM; + + for (i = 0; i < data->num_clks; i++) { + hw = _sci_clk_build(p, data->dev, i); + if (!IS_ERR(hw)) { + p->clocks[i] = hw; + continue; + } + + /* Skip any holes in the clock lists */ + if (PTR_ERR(hw) == -ENODEV) + continue; + + return PTR_ERR(hw); + } + data++; + } + + return 0; +} + +static const struct sci_clk_data k2g_clk_data[] = { + /* pmmc */ + { .dev = 0x0, .num_clks = 4 }, + + /* mlb0 */ + { .dev = 0x1, .num_clks = 5 }, + + /* dss0 */ + { .dev = 0x2, .num_clks = 2 }, + + /* mcbsp0 */ + { .dev = 0x3, .num_clks = 8 }, + + /* mcasp0 */ + { .dev = 0x4, .num_clks = 8 }, + + /* mcasp1 */ + { .dev = 0x5, .num_clks = 8 }, + + /* mcasp2 */ + { .dev = 0x6, .num_clks = 8 }, + + /* dcan0 */ + { .dev = 0x8, .num_clks = 2 }, + + /* dcan1 */ + { .dev = 0x9, .num_clks = 2 }, + + /* emif0 */ + { .dev = 0xa, .num_clks = 6 }, + + /* mmchs0 */ + { .dev = 0xb, .num_clks = 3 }, + + /* mmchs1 */ + { .dev = 0xc, .num_clks = 3 }, + + /* gpmc0 */ + { .dev = 0xd, .num_clks = 1 }, + + /* elm0 */ + { .dev = 0xe, .num_clks = 1 }, + + /* spi0 */ + { .dev = 0x10, .num_clks = 1 }, + + /* spi1 */ + { .dev = 0x11, .num_clks = 1 }, + + /* spi2 */ + { .dev = 0x12, .num_clks = 1 }, + + /* spi3 */ + { .dev = 0x13, .num_clks = 1 }, + + /* icss0 */ + { .dev = 0x14, .num_clks = 6 }, + + /* icss1 */ + { .dev = 0x15, .num_clks = 6 }, + + /* usb0 */ + { .dev = 0x16, .num_clks = 7 }, + + /* usb1 */ + { .dev = 0x17, .num_clks = 7 }, + + /* nss0 */ + { .dev = 0x18, .num_clks = 14 }, + + /* pcie0 */ + { .dev = 0x19, .num_clks = 1 }, + + /* gpio0 */ + { .dev = 0x1b, .num_clks = 1 }, + + /* gpio1 */ + { .dev = 0x1c, .num_clks = 1 }, + + /* timer64_0 */ + { .dev = 0x1d, .num_clks = 9 }, + + /* timer64_1 */ + { .dev = 0x1e, .num_clks = 9 }, + + /* timer64_2 */ + { .dev = 0x1f, .num_clks = 9 }, + + /* timer64_3 */ + { .dev = 0x20, .num_clks = 9 }, + + /* timer64_4 */ + { .dev = 0x21, .num_clks = 9 }, + + /* timer64_5 */ + { .dev = 0x22, .num_clks = 9 }, + + /* timer64_6 */ + { .dev = 0x23, .num_clks = 9 }, + + /* msgmgr0 */ + { .dev = 0x25, .num_clks = 1 }, + + /* bootcfg0 */ + { .dev = 0x26, .num_clks = 1 }, + + /* arm_bootrom0 */ + { .dev = 0x27, .num_clks = 1 }, + + /* dsp_bootrom0 */ + { .dev = 0x29, .num_clks = 1 }, + + /* debugss0 */ + { .dev = 0x2b, .num_clks = 8 }, + + /* uart0 */ + { .dev = 0x2c, .num_clks = 1 }, + + /* uart1 */ + { .dev = 0x2d, .num_clks = 1 }, + + /* uart2 */ + { .dev = 0x2e, .num_clks = 1 }, + + /* ehrpwm0 */ + { .dev = 0x2f, .num_clks = 1 }, + + /* ehrpwm1 */ + { .dev = 0x30, .num_clks = 1 }, + + /* ehrpwm2 */ + { .dev = 0x31, .num_clks = 1 }, + + /* ehrpwm3 */ + { .dev = 0x32, .num_clks = 1 }, + + /* ehrpwm4 */ + { .dev = 0x33, .num_clks = 1 }, + + /* ehrpwm5 */ + { .dev = 0x34, .num_clks = 1 }, + + /* eqep0 */ + { .dev = 0x35, .num_clks = 1 }, + + /* eqep1 */ + { .dev = 0x36, .num_clks = 1 }, + + /* eqep2 */ + { .dev = 0x37, .num_clks = 1 }, + + /* ecap0 */ + { .dev = 0x38, .num_clks = 1 }, + + /* ecap1 */ + { .dev = 0x39, .num_clks = 1 }, + + /* i2c0 */ + { .dev = 0x3a, .num_clks = 1 }, + + /* i2c1 */ + { .dev = 0x3b, .num_clks = 1 }, + + /* i2c2 */ + { .dev = 0x3c, .num_clks = 1 }, + + /* edma0 */ + { .dev = 0x3f, .num_clks = 2 }, + + /* semaphore0 */ + { .dev = 0x40, .num_clks = 1 }, + + /* intc0 */ + { .dev = 0x41, .num_clks = 1 }, + + /* gic0 */ + { .dev = 0x42, .num_clks = 1 }, + + /* qspi0 */ + { .dev = 0x43, .num_clks = 5 }, + + /* arm_64b_counter0 */ + { .dev = 0x44, .num_clks = 2 }, + + /* tetris0 */ + { .dev = 0x45, .num_clks = 2 }, + + /* cgem0 */ + { .dev = 0x46, .num_clks = 2 }, + + /* msmc0 */ + { .dev = 0x47, .num_clks = 1 }, + + /* cbass0 */ + { .dev = 0x49, .num_clks = 1 }, + + /* board0 */ + { .dev = 0x4c, .num_clks = 36 }, + + /* edma1 */ + { .dev = 0x4f, .num_clks = 2 }, + { .num_clks = 0 }, +}; + +static const struct of_device_id ti_sci_clk_of_match[] = { + { .compatible = "ti,k2g-sci-clk", .data = &k2g_clk_data }, + { /* Sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match); + +/** + * ti_sci_clk_probe - Probe function for the TI SCI clock driver + * @pdev: platform device pointer to be probed + * + * Probes the TI SCI clock device. Allocates a new clock provider + * and registers this to the common clock framework. Also applies + * any required flags to the identified clocks via clock lists + * supplied from DT. Returns 0 for success, negative error value + * for failure. + */ +static int ti_sci_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct sci_clk_provider *provider; + const struct ti_sci_handle *handle; + const struct sci_clk_data *data; + int ret; + + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + + handle = devm_ti_sci_get_handle(dev); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL); + if (!provider) + return -ENOMEM; + + provider->clk_data = data; + + provider->sci = handle; + provider->ops = &handle->ops.clk_ops; + provider->dev = dev; + + ret = ti_sci_init_clocks(provider); + if (ret) { + pr_err("ti-sci-init-clocks failed.\n"); + return ret; + } + + return of_clk_add_hw_provider(np, sci_clk_get, provider); +} + +/** + * ti_sci_clk_remove - Remove TI SCI clock device + * @pdev: platform device pointer for the device to be removed + * + * Removes the TI SCI device. Unregisters the clock provider registered + * via common clock framework. Any memory allocated for the device will + * be free'd silently via the devm framework. Returns 0 always. + */ +static int ti_sci_clk_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + + return 0; +} + +static struct platform_driver ti_sci_clk_driver = { + .probe = ti_sci_clk_probe, + .remove = ti_sci_clk_remove, + .driver = { + .name = "ti-sci-clk", + .of_match_table = of_match_ptr(ti_sci_clk_of_match), + }, +}; +module_platform_driver(ti_sci_clk_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver"); +MODULE_AUTHOR("Tero Kristo"); +MODULE_ALIAS("platform:ti-sci-clk"); diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 19480bcc7046..2f29ee1a4d00 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -14,6 +14,7 @@ config COMMON_CLK_MESON8B config COMMON_CLK_GXBB bool depends on COMMON_CLK_AMLOGIC + select RESET_CONTROLLER help Support for the clock controller on AmLogic S905 devices, aka gxbb. Say Y if you want peripherals and CPU frequency scaling to work. diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index ad5f027af1a2..36c0e455437e 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -278,20 +278,6 @@ static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { { /* sentinel */ }, }; -static const struct clk_div_table cpu_div_table[] = { - { .val = 1, .div = 1 }, - { .val = 2, .div = 2 }, - { .val = 3, .div = 3 }, - { .val = 2, .div = 4 }, - { .val = 3, .div = 6 }, - { .val = 4, .div = 8 }, - { .val = 5, .div = 10 }, - { .val = 6, .div = 12 }, - { .val = 7, .div = 14 }, - { .val = 8, .div = 16 }, - { /* sentinel */ }, -}; - static struct meson_clk_pll gxbb_fixed_pll = { .m = { .reg_off = HHI_MPLL_CNTL, @@ -612,21 +598,10 @@ static struct meson_clk_mpll gxbb_mpll2 = { }; /* - * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL - * post-dividers and should be modeled with their respective PLLs via the - * forthcoming coordinated clock rates feature + * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers + * and should be modeled with their respective PLLs via the forthcoming + * coordinated clock rates feature */ -static struct meson_clk_cpu gxbb_cpu_clk = { - .reg_off = HHI_SYS_CPU_CLK_CNTL1, - .div_table = cpu_div_table, - .clk_nb.notifier_call = meson_clk_cpu_notifier_cb, - .hw.init = &(struct clk_init_data){ - .name = "cpu_clk", - .ops = &meson_clk_cpu_ops, - .parent_names = (const char *[]){ "sys_pll" }, - .num_parents = 1, - }, -}; static u32 mux_table_clk81[] = { 6, 5, 7 }; @@ -676,7 +651,7 @@ static struct clk_gate gxbb_clk81 = { .ops = &clk_gate_ops, .parent_names = (const char *[]){ "mpeg_clk_div" }, .num_parents = 1, - .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL), + .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; @@ -726,7 +701,7 @@ static struct clk_gate gxbb_sar_adc_clk = { */ static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7}; -static const char *gxbb_mali_0_1_parent_names[] = { +static const char * const gxbb_mali_0_1_parent_names[] = { "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3", "fclk_div5" }; @@ -826,7 +801,7 @@ static struct clk_gate gxbb_mali_1 = { }; static u32 mux_table_mali[] = {0, 1}; -static const char *gxbb_mali_parent_names[] = { +static const char * const gxbb_mali_parent_names[] = { "mali_0", "mali_1" }; @@ -951,6 +926,51 @@ static struct clk_mux gxbb_cts_i958 = { }, }; +static struct clk_divider gxbb_32k_clk_div = { + .reg = (void *)HHI_32K_CLK_CNTL, + .shift = 0, + .width = 14, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "32k_clk_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "32k_clk_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, + }, +}; + +static struct clk_gate gxbb_32k_clk = { + .reg = (void *)HHI_32K_CLK_CNTL, + .bit_idx = 15, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "32k_clk", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "32k_clk_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const char * const gxbb_32k_clk_parent_names[] = { + "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5" +}; + +static struct clk_mux gxbb_32k_clk_sel = { + .reg = (void *)HHI_32K_CLK_CNTL, + .mask = 0x3, + .shift = 16, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "32k_clk_sel", + .ops = &clk_mux_ops, + .parent_names = gxbb_32k_clk_parent_names, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); @@ -1045,7 +1065,6 @@ static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4); static struct clk_hw_onecell_data gxbb_hw_onecell_data = { .hws = { [CLKID_SYS_PLL] = &gxbb_sys_pll.hw, - [CLKID_CPUCLK] = &gxbb_cpu_clk.hw, [CLKID_HDMI_PLL] = &gxbb_hdmi_pll.hw, [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw, [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw, @@ -1158,6 +1177,9 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { [CLKID_CTS_MCLK_I958_SEL] = &gxbb_cts_mclk_i958_sel.hw, [CLKID_CTS_MCLK_I958_DIV] = &gxbb_cts_mclk_i958_div.hw, [CLKID_CTS_I958] = &gxbb_cts_i958.hw, + [CLKID_32K_CLK] = &gxbb_32k_clk.hw, + [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, + [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, }, .num = NR_CLKS, }; @@ -1165,7 +1187,6 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { static struct clk_hw_onecell_data gxl_hw_onecell_data = { .hws = { [CLKID_SYS_PLL] = &gxbb_sys_pll.hw, - [CLKID_CPUCLK] = &gxbb_cpu_clk.hw, [CLKID_HDMI_PLL] = &gxbb_hdmi_pll.hw, [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw, [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw, @@ -1278,6 +1299,9 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_CTS_MCLK_I958_SEL] = &gxbb_cts_mclk_i958_sel.hw, [CLKID_CTS_MCLK_I958_DIV] = &gxbb_cts_mclk_i958_div.hw, [CLKID_CTS_I958] = &gxbb_cts_i958.hw, + [CLKID_32K_CLK] = &gxbb_32k_clk.hw, + [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, + [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, }, .num = NR_CLKS, }; @@ -1392,6 +1416,7 @@ static struct clk_gate *const gxbb_clk_gates[] = { &gxbb_mali_1, &gxbb_cts_amclk, &gxbb_cts_mclk_i958, + &gxbb_32k_clk, }; static struct clk_mux *const gxbb_clk_muxes[] = { @@ -1403,6 +1428,7 @@ static struct clk_mux *const gxbb_clk_muxes[] = { &gxbb_cts_amclk_sel, &gxbb_cts_mclk_i958_sel, &gxbb_cts_i958, + &gxbb_32k_clk_sel, }; static struct clk_divider *const gxbb_clk_dividers[] = { @@ -1411,6 +1437,7 @@ static struct clk_divider *const gxbb_clk_dividers[] = { &gxbb_mali_0_div, &gxbb_mali_1_div, &gxbb_cts_mclk_i958_div, + &gxbb_32k_clk_div, }; static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = { @@ -1430,7 +1457,6 @@ struct clkc_data { unsigned int clk_dividers_count; struct meson_clk_audio_divider *const *clk_audio_dividers; unsigned int clk_audio_dividers_count; - struct meson_clk_cpu *cpu_clk; struct clk_hw_onecell_data *hw_onecell_data; }; @@ -1447,7 +1473,6 @@ static const struct clkc_data gxbb_clkc_data = { .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers), .clk_audio_dividers = gxbb_audio_dividers, .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers), - .cpu_clk = &gxbb_cpu_clk, .hw_onecell_data = &gxbb_hw_onecell_data, }; @@ -1464,7 +1489,6 @@ static const struct clkc_data gxl_clkc_data = { .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers), .clk_audio_dividers = gxbb_audio_dividers, .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers), - .cpu_clk = &gxbb_cpu_clk, .hw_onecell_data = &gxl_hw_onecell_data, }; @@ -1479,8 +1503,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev) const struct clkc_data *clkc_data; void __iomem *clk_base; int ret, clkid, i; - struct clk_hw *parent_hw; - struct clk *parent_clk; struct device *dev = &pdev->dev; clkc_data = of_device_get_match_data(&pdev->dev); @@ -1502,9 +1524,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev) for (i = 0; i < clkc_data->clk_mplls_count; i++) clkc_data->clk_mplls[i]->base = clk_base; - /* Populate the base address for CPU clk */ - clkc_data->cpu_clk->base = clk_base; - /* Populate base address for gates */ for (i = 0; i < clkc_data->clk_gates_count; i++) clkc_data->clk_gates[i]->reg = clk_base + @@ -1538,29 +1557,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev) goto iounmap; } - /* - * Register CPU clk notifier - * - * FIXME this is wrong for a lot of reasons. First, the muxes should be - * struct clk_hw objects. Second, we shouldn't program the muxes in - * notifier handlers. The tricky programming sequence will be handled - * by the forthcoming coordinated clock rates mechanism once that - * feature is released. - * - * Furthermore, looking up the parent this way is terrible. At some - * point we will stop allocating a default struct clk when registering - * a new clk_hw, and this hack will no longer work. Releasing the ccr - * feature before that time solves the problem :-) - */ - parent_hw = clk_hw_get_parent(&clkc_data->cpu_clk->hw); - parent_clk = parent_hw->clk; - ret = clk_notifier_register(parent_clk, &clkc_data->cpu_clk->clk_nb); - if (ret) { - pr_err("%s: failed to register clock notifier for cpu_clk\n", - __func__); - goto iounmap; - } - return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, clkc_data->hw_onecell_data); diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index 93b8f07ee7af..d63e77e8433d 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -171,7 +171,7 @@ * to be exposed to client nodes in DT: include/dt-bindings/clock/gxbb-clkc.h */ #define CLKID_SYS_PLL 0 -/* CLKID_CPUCLK */ +/* ID 1 is unused (it was used by the non-existing CLKID_CPUCLK before) */ /* CLKID_HDMI_PLL */ #define CLKID_FIXED_PLL 3 /* CLKID_FCLK_DIV2 */ @@ -191,12 +191,12 @@ #define CLKID_ISA 18 #define CLKID_PL301 19 #define CLKID_PERIPHS 20 -#define CLKID_SPICC 21 +/* CLKID_SPICC */ /* CLKID_I2C */ /* #define CLKID_SAR_ADC */ #define CLKID_SMART_CARD 24 /* CLKID_RNG0 */ -#define CLKID_UART0 26 +/* CLKID_UART0 */ #define CLKID_SDHC 27 #define CLKID_STREAM 28 #define CLKID_ASYNC_FIFO 29 @@ -209,7 +209,7 @@ /* CLKID_ETH */ #define CLKID_DEMUX 37 /* CLKID_AIU_GLUE */ -#define CLKID_IEC958 39 +/* CLKID_IEC958 */ /* CLKID_I2S_OUT */ #define CLKID_AMCLK 41 #define CLKID_AIFIFO2 42 @@ -218,7 +218,7 @@ #define CLKID_ADC 45 #define CLKID_BLKMV 46 /* CLKID_AIU */ -#define CLKID_UART1 48 +/* CLKID_UART1 */ #define CLKID_G2D 49 /* CLKID_USB0 */ /* CLKID_USB1 */ @@ -238,7 +238,7 @@ /* CLKID_USB0_DDR_BRIDGE */ #define CLKID_MMC_PCLK 66 #define CLKID_DVIN 67 -#define CLKID_UART2 68 +/* CLKID_UART2 */ /* #define CLKID_SANA */ #define CLKID_VPU_INTR 70 #define CLKID_SEC_AHB_AHB3_BRIDGE 71 @@ -251,7 +251,7 @@ #define CLKID_GCLK_VENCI_INT 78 #define CLKID_DAC_CLK 79 /* CLKID_AOCLK_GATE */ -#define CLKID_IEC958_GATE 81 +/* CLKID_IEC958_GATE */ #define CLKID_ENC480P 82 #define CLKID_RNG1 83 #define CLKID_GCLK_VENCI_INT1 84 @@ -277,15 +277,18 @@ #define CLKID_MALI_1_DIV 104 /* CLKID_MALI_1 */ /* CLKID_MALI */ -#define CLKID_CTS_AMCLK 107 +/* CLKID_CTS_AMCLK */ #define CLKID_CTS_AMCLK_SEL 108 #define CLKID_CTS_AMCLK_DIV 109 -#define CLKID_CTS_MCLK_I958 110 +/* CLKID_CTS_MCLK_I958 */ #define CLKID_CTS_MCLK_I958_SEL 111 #define CLKID_CTS_MCLK_I958_DIV 112 -#define CLKID_CTS_I958 113 +/* CLKID_CTS_I958 */ +#define CLKID_32K_CLK 114 +#define CLKID_32K_CLK_SEL 115 +#define CLKID_32K_CLK_DIV 116 -#define NR_CLKS 114 +#define NR_CLKS 117 /* include the CLKIDs that have been made part of the stable DT binding */ #include <dt-bindings/clock/gxbb-clkc.h> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index e9985503165c..9d1aaf6e9ac6 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -399,7 +399,7 @@ struct clk_gate meson8b_clk81 = { .ops = &clk_gate_ops, .parent_names = (const char *[]){ "mpeg_clk_div" }, .num_parents = 1, - .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), + .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index 8155baccc98e..fa2fbd2cef4a 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -32,24 +32,38 @@ static struct clk_onecell_data ap806_clk_data = { .clk_num = AP806_CLK_NUM, }; -static int ap806_syscon_clk_probe(struct platform_device *pdev) +static char *ap806_unique_name(struct device *dev, struct device_node *np, + char *name) +{ + const __be32 *reg; + u64 addr; + + reg = of_get_property(np, "reg", NULL); + addr = of_translate_address(np, reg); + return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s", + (unsigned long long)addr, name); +} + +static int ap806_syscon_common_probe(struct platform_device *pdev, + struct device_node *syscon_node) { unsigned int freq_mode, cpuclk_freq; const char *name, *fixedclk_name; - struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct regmap *regmap; u32 reg; int ret; - regmap = syscon_node_to_regmap(np); + regmap = syscon_node_to_regmap(syscon_node); if (IS_ERR(regmap)) { - dev_err(&pdev->dev, "cannot get regmap\n"); + dev_err(dev, "cannot get regmap\n"); return PTR_ERR(regmap); } ret = regmap_read(regmap, AP806_SAR_REG, ®); if (ret) { - dev_err(&pdev->dev, "cannot read from regmap\n"); + dev_err(dev, "cannot read from regmap\n"); return ret; } @@ -89,7 +103,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev) cpuclk_freq = 600; break; default: - dev_err(&pdev->dev, "invalid SAR value\n"); + dev_err(dev, "invalid SAR value\n"); return -EINVAL; } @@ -97,18 +111,16 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev) cpuclk_freq *= 1000 * 1000; /* CPU clocks depend on the Sample At Reset configuration */ - of_property_read_string_index(np, "clock-output-names", - 0, &name); - ap806_clks[0] = clk_register_fixed_rate(&pdev->dev, name, NULL, + name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0"); + ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL, 0, cpuclk_freq); if (IS_ERR(ap806_clks[0])) { ret = PTR_ERR(ap806_clks[0]); goto fail0; } - of_property_read_string_index(np, "clock-output-names", - 1, &name); - ap806_clks[1] = clk_register_fixed_rate(&pdev->dev, name, NULL, 0, + name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1"); + ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0, cpuclk_freq); if (IS_ERR(ap806_clks[1])) { ret = PTR_ERR(ap806_clks[1]); @@ -116,9 +128,8 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev) } /* Fixed clock is always 1200 Mhz */ - of_property_read_string_index(np, "clock-output-names", - 2, &fixedclk_name); - ap806_clks[2] = clk_register_fixed_rate(&pdev->dev, fixedclk_name, NULL, + fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed"); + ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL, 0, 1200 * 1000 * 1000); if (IS_ERR(ap806_clks[2])) { ret = PTR_ERR(ap806_clks[2]); @@ -126,8 +137,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev) } /* MSS Clock is fixed clock divided by 6 */ - of_property_read_string_index(np, "clock-output-names", - 3, &name); + name = ap806_unique_name(dev, syscon_node, "mss"); ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name, 0, 1, 6); if (IS_ERR(ap806_clks[3])) { @@ -135,20 +145,14 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev) goto fail3; } - /* eMMC Clock is fixed clock divided by 3 */ - if (of_property_read_string_index(np, "clock-output-names", - 4, &name)) { - ap806_clk_data.clk_num--; - dev_warn(&pdev->dev, - "eMMC clock missing: update the device tree!\n"); - } else { - ap806_clks[4] = clk_register_fixed_factor(NULL, name, - fixedclk_name, - 0, 1, 3); - if (IS_ERR(ap806_clks[4])) { - ret = PTR_ERR(ap806_clks[4]); - goto fail4; - } + /* SDIO(/eMMC) Clock is fixed clock divided by 3 */ + name = ap806_unique_name(dev, syscon_node, "sdio"); + ap806_clks[4] = clk_register_fixed_factor(NULL, name, + fixedclk_name, + 0, 1, 3); + if (IS_ERR(ap806_clks[4])) { + ret = PTR_ERR(ap806_clks[4]); + goto fail4; } of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); @@ -172,17 +176,48 @@ fail0: return ret; } -static const struct of_device_id ap806_syscon_of_match[] = { +static int ap806_syscon_legacy_probe(struct platform_device *pdev) +{ + dev_warn(&pdev->dev, FW_WARN "Using legacy device tree binding\n"); + dev_warn(&pdev->dev, FW_WARN "Update your device tree:\n"); + dev_warn(&pdev->dev, FW_WARN + "This binding won't be supported in future kernel\n"); + + return ap806_syscon_common_probe(pdev, pdev->dev.of_node); + +} + +static int ap806_clock_probe(struct platform_device *pdev) +{ + return ap806_syscon_common_probe(pdev, pdev->dev.of_node->parent); +} + +static const struct of_device_id ap806_syscon_legacy_of_match[] = { { .compatible = "marvell,ap806-system-controller", }, { } }; -static struct platform_driver ap806_syscon_driver = { - .probe = ap806_syscon_clk_probe, +static struct platform_driver ap806_syscon_legacy_driver = { + .probe = ap806_syscon_legacy_probe, .driver = { .name = "marvell-ap806-system-controller", - .of_match_table = ap806_syscon_of_match, + .of_match_table = ap806_syscon_legacy_of_match, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver(ap806_syscon_legacy_driver); + +static const struct of_device_id ap806_clock_of_match[] = { + { .compatible = "marvell,ap806-clock", }, + { } +}; + +static struct platform_driver ap806_clock_driver = { + .probe = ap806_clock_probe, + .driver = { + .name = "marvell-ap806-clock", + .of_match_table = ap806_clock_of_match, .suppress_bind_attrs = true, }, }; -builtin_platform_driver(ap806_syscon_driver); +builtin_platform_driver(ap806_clock_driver); diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c index 8bccf4ecdab6..394aa6f03f01 100644 --- a/drivers/clk/mvebu/armada-38x.c +++ b/drivers/clk/mvebu/armada-38x.c @@ -49,7 +49,8 @@ static const u32 armada_38x_cpu_frequencies[] __initconst = { 0, 0, 0, 0, 1066 * 1000 * 1000, 0, 0, 0, 1332 * 1000 * 1000, 0, 0, 0, - 1600 * 1000 * 1000, + 1600 * 1000 * 1000, 0, 0, 0, + 1866 * 1000 * 1000, }; static u32 __init armada_38x_get_cpu_freq(void __iomem *sar) @@ -79,7 +80,7 @@ static const int armada_38x_cpu_l2_ratios[32][2] __initconst = { {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, @@ -90,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = { {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 2586dfa0026b..78d1df9112ba 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -1,20 +1,129 @@ +config CLK_RENESAS + bool "Renesas SoC clock support" if COMPILE_TEST && !ARCH_RENESAS + default y if ARCH_RENESAS + select CLK_EMEV2 if ARCH_EMEV2 + select CLK_RZA1 if ARCH_R7S72100 + select CLK_R8A73A4 if ARCH_R8A73A4 + select CLK_R8A7740 if ARCH_R8A7740 + select CLK_R8A7743 if ARCH_R8A7743 + select CLK_R8A7745 if ARCH_R8A7745 + select CLK_R8A7778 if ARCH_R8A7778 + select CLK_R8A7779 if ARCH_R8A7779 + select CLK_R8A7790 if ARCH_R8A7790 + 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_R8A7795 + select CLK_R8A7796 if ARCH_R8A7796 + select CLK_SH73A0 if ARCH_SH73A0 + +if CLK_RENESAS + +config CLK_RENESAS_LEGACY + bool "Legacy DT clock support" + depends on CLK_R8A7790 || CLK_R8A7791 || CLK_R8A7792 || CLK_R8A7794 + default y + help + Enable backward compatibility with old device trees describing a + hierarchical representation of the various CPG and MSTP clocks. + + Say Y if you want your kernel to work with old DTBs. + +# SoC +config CLK_EMEV2 + bool "Emma Mobile EV2 clock support" if COMPILE_TEST + +config CLK_RZA1 + bool + select CLK_RENESAS_CPG_MSTP + +config CLK_R8A73A4 + bool + select CLK_RENESAS_CPG_MSTP + select CLK_RENESAS_DIV6 + +config CLK_R8A7740 + bool + select CLK_RENESAS_CPG_MSTP + select CLK_RENESAS_DIV6 + +config CLK_R8A7743 + bool + select CLK_RCAR_GEN2_CPG + +config CLK_R8A7745 + bool + select CLK_RCAR_GEN2_CPG + +config CLK_R8A7778 + bool + select CLK_RENESAS_CPG_MSTP + +config CLK_R8A7779 + bool + select CLK_RENESAS_CPG_MSTP + +config CLK_R8A7790 + bool + select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY + select CLK_RCAR_GEN2_CPG + select CLK_RENESAS_DIV6 + +config CLK_R8A7791 + bool + select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY + select CLK_RCAR_GEN2_CPG + select CLK_RENESAS_DIV6 + +config CLK_R8A7792 + bool + select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY + select CLK_RCAR_GEN2_CPG + +config CLK_R8A7794 + bool + select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY + select CLK_RCAR_GEN2_CPG + select CLK_RENESAS_DIV6 + +config CLK_R8A7795 + bool + select CLK_RCAR_GEN3_CPG + +config CLK_R8A7796 + bool + select CLK_RCAR_GEN3_CPG + +config CLK_SH73A0 + bool + select CLK_RENESAS_CPG_MSTP + select CLK_RENESAS_DIV6 + + +# Family +config CLK_RCAR_GEN2 + bool + select CLK_RENESAS_CPG_MSTP + select CLK_RENESAS_DIV6 + +config CLK_RCAR_GEN2_CPG + bool + select CLK_RENESAS_CPG_MSSR + +config CLK_RCAR_GEN3_CPG + bool + select CLK_RENESAS_CPG_MSSR + + +# Generic config CLK_RENESAS_CPG_MSSR bool - default y if ARCH_R8A7743 - default y if ARCH_R8A7745 - default y if ARCH_R8A7795 - default y if ARCH_R8A7796 + select CLK_RENESAS_DIV6 config CLK_RENESAS_CPG_MSTP bool - default y if ARCH_R7S72100 - default y if ARCH_R8A73A4 - default y if ARCH_R8A7740 - default y if ARCH_R8A7778 - default y if ARCH_R8A7779 - default y if ARCH_R8A7790 - default y if ARCH_R8A7791 - default y if ARCH_R8A7792 - default y if ARCH_R8A7793 - default y if ARCH_R8A7794 - default y if ARCH_SH73A0 + +config CLK_RENESAS_DIV6 + bool "DIV6 clock support" if COMPILE_TEST + +endif # CLK_RENESAS diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 1072f7653c0c..02d04124371f 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -1,19 +1,26 @@ -obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o -obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o -obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7743) += r8a7743-cpg-mssr.o rcar-gen2-cpg.o -obj-$(CONFIG_ARCH_R8A7745) += r8a7745-cpg-mssr.o rcar-gen2-cpg.o -obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o -obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o -obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7792) += clk-rcar-gen2.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o -obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o -obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o +# SoC +obj-$(CONFIG_CLK_EMEV2) += clk-emev2.o +obj-$(CONFIG_CLK_RZA1) += clk-rz.o +obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o +obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o +obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o +obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o +obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7791) += r8a7791-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o +obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o -obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o +# Family +obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o +obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o +obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o + +# Generic +obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o obj-$(CONFIG_CLK_RENESAS_CPG_MSTP) += clk-mstp.o +obj-$(CONFIG_CLK_RENESAS_DIV6) += clk-div6.o diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 4067216bf31f..f1617dd044cb 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -325,7 +325,7 @@ fail_put: void cpg_mstp_detach_dev(struct generic_pm_domain *unused, struct device *dev) { - if (!list_empty(&dev->power.subsys_data->clock_list)) + if (!pm_clk_no_clocks(dev)) pm_clk_destroy(dev); } diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index f39519edc645..51a2479ed5d7 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -272,11 +272,14 @@ struct cpg_pll_config { unsigned int extal_div; unsigned int pll1_mult; unsigned int pll3_mult; + unsigned int pll0_mult; /* For R-Car V2H and E2 only */ }; static const struct cpg_pll_config cpg_pll_configs[8] __initconst = { - { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 }, - { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 }, + { 1, 208, 106, 200 }, { 1, 208, 88, 200 }, + { 1, 156, 80, 150 }, { 1, 156, 66, 150 }, + { 2, 240, 122, 230 }, { 2, 240, 102, 230 }, + { 2, 208, 106, 200 }, { 2, 208, 88, 200 }, }; /* SDHI divisors */ @@ -298,6 +301,12 @@ static const struct clk_div_table cpg_sd01_div_table[] = { static u32 cpg_mode __initdata; +static const char * const pll0_mult_match[] = { + "renesas,r8a7792-cpg-clocks", + "renesas,r8a7794-cpg-clocks", + NULL +}; + static struct clk * __init rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, const struct cpg_pll_config *config, @@ -318,9 +327,15 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, * clock implementation and we currently have no need to change * the multiplier value. */ - u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + if (of_device_compatible_match(np, pll0_mult_match)) { + /* R-Car V2H and E2 do not have PLL0CR */ + mult = config->pll0_mult; + div = 3; + } else { + u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + mult = ((value >> 24) & ((1 << 7) - 1)) + 1; + } parent_name = "main"; - mult = ((value >> 24) & ((1 << 7) - 1)) + 1; } else if (!strcmp(name, "pll1")) { parent_name = "main"; mult = config->pll1_mult / 2; diff --git a/drivers/clk/renesas/r8a7745-cpg-mssr.c b/drivers/clk/renesas/r8a7745-cpg-mssr.c index 2f15ba786c3b..9e2360a8e14b 100644 --- a/drivers/clk/renesas/r8a7745-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7745-cpg-mssr.c @@ -167,16 +167,12 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), - DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), - DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), - DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), - DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), DEF_MOD("scifa3", 1106, R8A7745_CLK_MP), DEF_MOD("scifa4", 1107, R8A7745_CLK_MP), DEF_MOD("scifa5", 1108, R8A7745_CLK_MP), @@ -194,31 +190,22 @@ static const unsigned int r8a7745_crit_mod_clks[] __initconst = { * MD EXTAL PLL0 PLL1 PLL3 * 14 13 19 (MHz) *1 *2 *--------------------------------------------------- - * 0 0 0 15 x200/3 x208/2 x106 * 0 0 1 15 x200/3 x208/2 x88 - * 0 1 0 20 x150/3 x156/2 x80 * 0 1 1 20 x150/3 x156/2 x66 - * 1 0 0 26 / 2 x230/3 x240/2 x122 * 1 0 1 26 / 2 x230/3 x240/2 x102 - * 1 1 0 30 / 2 x200/3 x208/2 x106 * 1 1 1 30 / 2 x200/3 x208/2 x88 * * *1 : Table 7.5b indicates VCO output (PLL0 = VCO/3) * *2 : Table 7.5b indicates VCO output (PLL1 = VCO/2) */ -#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ - (((md) & BIT(13)) >> 12) | \ - (((md) & BIT(19)) >> 19)) +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \ + (((md) & BIT(13)) >> 13)) static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = { /* EXTAL div PLL1 mult PLL3 mult PLL0 mult */ - { 1, 208, 106, 200 }, { 1, 208, 88, 200 }, - { 1, 156, 80, 150 }, { 1, 156, 66, 150 }, - { 2, 240, 122, 230 }, { 2, 240, 102, 230 }, - { 2, 208, 106, 200 }, { 2, 208, 88, 200 }, }; diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c new file mode 100644 index 000000000000..46bb55bb223d --- /dev/null +++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c @@ -0,0 +1,278 @@ +/* + * r8a7790 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2017 Glider bvba + * + * Based on clk-rcar-gen2.c + * + * Copyright (C) 2013 Ideas On Board SPRL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/soc/renesas/rcar-rst.h> + +#include <dt-bindings/clock/r8a7790-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen2-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7790_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_USB_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL1_DIV2, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a7790_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("usb_extal", CLK_USB_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_BASE("z", R8A7790_CLK_Z, CLK_TYPE_GEN2_Z, CLK_PLL0), + DEF_BASE("lb", R8A7790_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), + DEF_BASE("adsp", R8A7790_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1), + DEF_BASE("sdh", R8A7790_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), + DEF_BASE("sd0", R8A7790_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), + DEF_BASE("sd1", R8A7790_CLK_SD1, CLK_TYPE_GEN2_SD1, CLK_PLL1), + DEF_BASE("qspi", R8A7790_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), + DEF_BASE("rcan", R8A7790_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL), + + DEF_FIXED("z2", R8A7790_CLK_Z2, CLK_PLL1, 2, 1), + DEF_FIXED("zg", R8A7790_CLK_ZG, CLK_PLL1, 3, 1), + DEF_FIXED("zx", R8A7790_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("zs", R8A7790_CLK_ZS, CLK_PLL1, 6, 1), + DEF_FIXED("hp", R8A7790_CLK_HP, CLK_PLL1, 12, 1), + DEF_FIXED("i", R8A7790_CLK_I, CLK_PLL1, 2, 1), + DEF_FIXED("b", R8A7790_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("p", R8A7790_CLK_P, CLK_PLL1, 24, 1), + DEF_FIXED("cl", R8A7790_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("m2", R8A7790_CLK_M2, CLK_PLL1, 8, 1), + DEF_FIXED("imp", R8A7790_CLK_IMP, CLK_PLL1, 4, 1), + DEF_FIXED("zb3", R8A7790_CLK_ZB3, CLK_PLL3, 4, 1), + DEF_FIXED("zb3d2", R8A7790_CLK_ZB3D2, CLK_PLL3, 8, 1), + DEF_FIXED("ddr", R8A7790_CLK_DDR, CLK_PLL3, 8, 1), + DEF_FIXED("mp", R8A7790_CLK_MP, CLK_PLL1_DIV2, 15, 1), + DEF_FIXED("cp", R8A7790_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("r", R8A7790_CLK_R, CLK_PLL1, 49152, 1), + DEF_FIXED("osc", R8A7790_CLK_OSC, CLK_PLL1, 12288, 1), + + DEF_DIV6P1("sd2", R8A7790_CLK_SD2, CLK_PLL1_DIV2, 0x078), + DEF_DIV6P1("sd3", R8A7790_CLK_SD3, CLK_PLL1_DIV2, 0x26c), + DEF_DIV6P1("mmc0", R8A7790_CLK_MMC0, CLK_PLL1_DIV2, 0x240), + DEF_DIV6P1("mmc1", R8A7790_CLK_MMC1, CLK_PLL1_DIV2, 0x244), + DEF_DIV6P1("ssp", R8A7790_CLK_SSP, CLK_PLL1_DIV2, 0x248), + DEF_DIV6P1("ssprs", R8A7790_CLK_SSPRS, CLK_PLL1_DIV2, 0x24c), +}; + +static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { + DEF_MOD("msiof0", 0, R8A7790_CLK_MP), + DEF_MOD("vcp1", 100, R8A7790_CLK_ZS), + DEF_MOD("vcp0", 101, R8A7790_CLK_ZS), + DEF_MOD("vpc1", 102, R8A7790_CLK_ZS), + DEF_MOD("vpc0", 103, R8A7790_CLK_ZS), + DEF_MOD("jpu", 106, R8A7790_CLK_M2), + DEF_MOD("ssp1", 109, R8A7790_CLK_ZS), + DEF_MOD("tmu1", 111, R8A7790_CLK_P), + DEF_MOD("3dg", 112, R8A7790_CLK_ZG), + DEF_MOD("2d-dmac", 115, R8A7790_CLK_ZS), + DEF_MOD("fdp1-2", 117, R8A7790_CLK_ZS), + DEF_MOD("fdp1-1", 118, R8A7790_CLK_ZS), + DEF_MOD("fdp1-0", 119, R8A7790_CLK_ZS), + DEF_MOD("tmu3", 121, R8A7790_CLK_P), + DEF_MOD("tmu2", 122, R8A7790_CLK_P), + DEF_MOD("cmt0", 124, R8A7790_CLK_R), + DEF_MOD("tmu0", 125, R8A7790_CLK_CP), + DEF_MOD("vsp1du1", 127, R8A7790_CLK_ZS), + DEF_MOD("vsp1du0", 128, R8A7790_CLK_ZS), + DEF_MOD("vsp1-rt", 130, R8A7790_CLK_ZS), + DEF_MOD("vsp1-sy", 131, R8A7790_CLK_ZS), + DEF_MOD("scifa2", 202, R8A7790_CLK_MP), + DEF_MOD("scifa1", 203, R8A7790_CLK_MP), + DEF_MOD("scifa0", 204, R8A7790_CLK_MP), + DEF_MOD("msiof2", 205, R8A7790_CLK_MP), + DEF_MOD("scifb0", 206, R8A7790_CLK_MP), + DEF_MOD("scifb1", 207, R8A7790_CLK_MP), + DEF_MOD("msiof1", 208, R8A7790_CLK_MP), + DEF_MOD("msiof3", 215, R8A7790_CLK_MP), + DEF_MOD("scifb2", 216, R8A7790_CLK_MP), + DEF_MOD("sys-dmac1", 218, R8A7790_CLK_ZS), + DEF_MOD("sys-dmac0", 219, R8A7790_CLK_ZS), + DEF_MOD("iic2", 300, R8A7790_CLK_HP), + DEF_MOD("tpu0", 304, R8A7790_CLK_CP), + DEF_MOD("mmcif1", 305, R8A7790_CLK_MMC1), + DEF_MOD("scif2", 310, R8A7790_CLK_P), + DEF_MOD("sdhi3", 311, R8A7790_CLK_SD3), + DEF_MOD("sdhi2", 312, R8A7790_CLK_SD2), + DEF_MOD("sdhi1", 313, R8A7790_CLK_SD1), + DEF_MOD("sdhi0", 314, R8A7790_CLK_SD0), + DEF_MOD("mmcif0", 315, R8A7790_CLK_MMC0), + DEF_MOD("iic0", 318, R8A7790_CLK_HP), + DEF_MOD("pciec", 319, R8A7790_CLK_MP), + DEF_MOD("iic1", 323, R8A7790_CLK_HP), + DEF_MOD("usb3.0", 328, R8A7790_CLK_MP), + DEF_MOD("cmt1", 329, R8A7790_CLK_R), + DEF_MOD("usbhs-dmac0", 330, R8A7790_CLK_HP), + DEF_MOD("usbhs-dmac1", 331, R8A7790_CLK_HP), + DEF_MOD("irqc", 407, R8A7790_CLK_CP), + DEF_MOD("intc-sys", 408, R8A7790_CLK_ZS), + DEF_MOD("audio-dmac1", 501, R8A7790_CLK_HP), + DEF_MOD("audio-dmac0", 502, R8A7790_CLK_HP), + DEF_MOD("adsp_mod", 506, R8A7790_CLK_ADSP), + DEF_MOD("thermal", 522, CLK_EXTAL), + DEF_MOD("pwm", 523, R8A7790_CLK_P), + DEF_MOD("usb-ehci", 703, R8A7790_CLK_MP), + DEF_MOD("usbhs", 704, R8A7790_CLK_HP), + DEF_MOD("hscif1", 716, R8A7790_CLK_ZS), + DEF_MOD("hscif0", 717, R8A7790_CLK_ZS), + DEF_MOD("scif1", 720, R8A7790_CLK_P), + DEF_MOD("scif0", 721, R8A7790_CLK_P), + DEF_MOD("du2", 722, R8A7790_CLK_ZX), + DEF_MOD("du1", 723, R8A7790_CLK_ZX), + DEF_MOD("du0", 724, R8A7790_CLK_ZX), + DEF_MOD("lvds1", 725, R8A7790_CLK_ZX), + DEF_MOD("lvds0", 726, R8A7790_CLK_ZX), + DEF_MOD("mlb", 802, R8A7790_CLK_HP), + DEF_MOD("vin3", 808, R8A7790_CLK_ZG), + DEF_MOD("vin2", 809, R8A7790_CLK_ZG), + DEF_MOD("vin1", 810, R8A7790_CLK_ZG), + DEF_MOD("vin0", 811, R8A7790_CLK_ZG), + DEF_MOD("etheravb", 812, R8A7790_CLK_HP), + DEF_MOD("ether", 813, R8A7790_CLK_P), + DEF_MOD("sata1", 814, R8A7790_CLK_ZS), + DEF_MOD("sata0", 815, R8A7790_CLK_ZS), + DEF_MOD("gyro-adc", 901, R8A7790_CLK_P), + DEF_MOD("gpio5", 907, R8A7790_CLK_CP), + DEF_MOD("gpio4", 908, R8A7790_CLK_CP), + DEF_MOD("gpio3", 909, R8A7790_CLK_CP), + DEF_MOD("gpio2", 910, R8A7790_CLK_CP), + DEF_MOD("gpio1", 911, R8A7790_CLK_CP), + DEF_MOD("gpio0", 912, R8A7790_CLK_CP), + DEF_MOD("can1", 915, R8A7790_CLK_P), + DEF_MOD("can0", 916, R8A7790_CLK_P), + DEF_MOD("qspi_mod", 917, R8A7790_CLK_QSPI), + DEF_MOD("iicdvfs", 926, R8A7790_CLK_CP), + DEF_MOD("i2c3", 928, R8A7790_CLK_HP), + DEF_MOD("i2c2", 929, R8A7790_CLK_HP), + DEF_MOD("i2c1", 930, R8A7790_CLK_HP), + DEF_MOD("i2c0", 931, R8A7790_CLK_HP), + DEF_MOD("ssi-all", 1005, R8A7790_CLK_P), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A7790_CLK_P), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a7790_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-SYS (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x172/2 x208/2 x106 + * 0 0 1 15 x172/2 x208/2 x88 + * 0 1 0 20 x130/2 x156/2 x80 + * 0 1 1 20 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.5a indicates VCO output (PLLx = VCO/2) + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ + (((md) & BIT(13)) >> 12) | \ + (((md) & BIT(19)) >> 19)) +static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = { + { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 }, + { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 }, +}; + +static int __init r8a7790_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen2_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode); +} + +const struct cpg_mssr_info r8a7790_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7790_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7790_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7790_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7790_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7790_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7790_crit_mod_clks), + + /* Callbacks */ + .init = r8a7790_cpg_mssr_init, + .cpg_clk_register = rcar_gen2_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c new file mode 100644 index 000000000000..c0b51f9bb278 --- /dev/null +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c @@ -0,0 +1,286 @@ +/* + * r8a7791 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015-2017 Glider bvba + * + * Based on clk-rcar-gen2.c + * + * Copyright (C) 2013 Ideas On Board SPRL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/soc/renesas/rcar-rst.h> + +#include <dt-bindings/clock/r8a7791-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen2-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7791_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_USB_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL1_DIV2, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static struct cpg_core_clk r8a7791_core_clks[] __initdata = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("usb_extal", CLK_USB_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_BASE("z", R8A7791_CLK_Z, CLK_TYPE_GEN2_Z, CLK_PLL0), + DEF_BASE("lb", R8A7791_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), + DEF_BASE("adsp", R8A7791_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1), + DEF_BASE("sdh", R8A7791_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), + DEF_BASE("sd0", R8A7791_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), + DEF_BASE("qspi", R8A7791_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), + DEF_BASE("rcan", R8A7791_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL), + + DEF_FIXED("zg", R8A7791_CLK_ZG, CLK_PLL1, 3, 1), + DEF_FIXED("zx", R8A7791_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("zs", R8A7791_CLK_ZS, CLK_PLL1, 6, 1), + DEF_FIXED("hp", R8A7791_CLK_HP, CLK_PLL1, 12, 1), + DEF_FIXED("i", R8A7791_CLK_I, CLK_PLL1, 2, 1), + DEF_FIXED("b", R8A7791_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("p", R8A7791_CLK_P, CLK_PLL1, 24, 1), + DEF_FIXED("cl", R8A7791_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("m2", R8A7791_CLK_M2, CLK_PLL1, 8, 1), + DEF_FIXED("zb3", R8A7791_CLK_ZB3, CLK_PLL3, 4, 1), + DEF_FIXED("zb3d2", R8A7791_CLK_ZB3D2, CLK_PLL3, 8, 1), + DEF_FIXED("ddr", R8A7791_CLK_DDR, CLK_PLL3, 8, 1), + DEF_FIXED("mp", R8A7791_CLK_MP, CLK_PLL1_DIV2, 15, 1), + DEF_FIXED("cp", R8A7791_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("r", R8A7791_CLK_R, CLK_PLL1, 49152, 1), + DEF_FIXED("osc", R8A7791_CLK_OSC, CLK_PLL1, 12288, 1), + + DEF_DIV6P1("sd2", R8A7791_CLK_SD2, CLK_PLL1_DIV2, 0x078), + DEF_DIV6P1("sd3", R8A7791_CLK_SD3, CLK_PLL1_DIV2, 0x26c), + DEF_DIV6P1("mmc0", R8A7791_CLK_MMC0, CLK_PLL1_DIV2, 0x240), + DEF_DIV6P1("ssp", R8A7791_CLK_SSP, CLK_PLL1_DIV2, 0x248), + DEF_DIV6P1("ssprs", R8A7791_CLK_SSPRS, CLK_PLL1_DIV2, 0x24c), +}; + +static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { + DEF_MOD("msiof0", 0, R8A7791_CLK_MP), + DEF_MOD("vcp0", 101, R8A7791_CLK_ZS), + DEF_MOD("vpc0", 103, R8A7791_CLK_ZS), + DEF_MOD("jpu", 106, R8A7791_CLK_M2), + DEF_MOD("ssp1", 109, R8A7791_CLK_ZS), + DEF_MOD("tmu1", 111, R8A7791_CLK_P), + DEF_MOD("3dg", 112, R8A7791_CLK_ZG), + DEF_MOD("2d-dmac", 115, R8A7791_CLK_ZS), + DEF_MOD("fdp1-1", 118, R8A7791_CLK_ZS), + DEF_MOD("fdp1-0", 119, R8A7791_CLK_ZS), + DEF_MOD("tmu3", 121, R8A7791_CLK_P), + DEF_MOD("tmu2", 122, R8A7791_CLK_P), + DEF_MOD("cmt0", 124, R8A7791_CLK_R), + DEF_MOD("tmu0", 125, R8A7791_CLK_CP), + DEF_MOD("vsp1du1", 127, R8A7791_CLK_ZS), + DEF_MOD("vsp1du0", 128, R8A7791_CLK_ZS), + DEF_MOD("vsp1-sy", 131, R8A7791_CLK_ZS), + DEF_MOD("scifa2", 202, R8A7791_CLK_MP), + DEF_MOD("scifa1", 203, R8A7791_CLK_MP), + DEF_MOD("scifa0", 204, R8A7791_CLK_MP), + DEF_MOD("msiof2", 205, R8A7791_CLK_MP), + DEF_MOD("scifb0", 206, R8A7791_CLK_MP), + DEF_MOD("scifb1", 207, R8A7791_CLK_MP), + DEF_MOD("msiof1", 208, R8A7791_CLK_MP), + DEF_MOD("scifb2", 216, R8A7791_CLK_MP), + DEF_MOD("sys-dmac1", 218, R8A7791_CLK_ZS), + DEF_MOD("sys-dmac0", 219, R8A7791_CLK_ZS), + DEF_MOD("tpu0", 304, R8A7791_CLK_CP), + DEF_MOD("sdhi3", 311, R8A7791_CLK_SD3), + DEF_MOD("sdhi2", 312, R8A7791_CLK_SD2), + DEF_MOD("sdhi0", 314, R8A7791_CLK_SD0), + DEF_MOD("mmcif0", 315, R8A7791_CLK_MMC0), + DEF_MOD("iic0", 318, R8A7791_CLK_HP), + DEF_MOD("pciec", 319, R8A7791_CLK_MP), + DEF_MOD("iic1", 323, R8A7791_CLK_HP), + DEF_MOD("usb3.0", 328, R8A7791_CLK_MP), + DEF_MOD("cmt1", 329, R8A7791_CLK_R), + DEF_MOD("usbhs-dmac0", 330, R8A7791_CLK_HP), + DEF_MOD("usbhs-dmac1", 331, R8A7791_CLK_HP), + DEF_MOD("irqc", 407, R8A7791_CLK_CP), + DEF_MOD("intc-sys", 408, R8A7791_CLK_ZS), + DEF_MOD("audio-dmac1", 501, R8A7791_CLK_HP), + DEF_MOD("audio-dmac0", 502, R8A7791_CLK_HP), + DEF_MOD("adsp_mod", 506, R8A7791_CLK_ADSP), + DEF_MOD("thermal", 522, CLK_EXTAL), + DEF_MOD("pwm", 523, R8A7791_CLK_P), + DEF_MOD("usb-ehci", 703, R8A7791_CLK_MP), + DEF_MOD("usbhs", 704, R8A7791_CLK_HP), + DEF_MOD("hscif2", 713, R8A7791_CLK_ZS), + DEF_MOD("scif5", 714, R8A7791_CLK_P), + DEF_MOD("scif4", 715, R8A7791_CLK_P), + DEF_MOD("hscif1", 716, R8A7791_CLK_ZS), + DEF_MOD("hscif0", 717, R8A7791_CLK_ZS), + DEF_MOD("scif3", 718, R8A7791_CLK_P), + DEF_MOD("scif2", 719, R8A7791_CLK_P), + DEF_MOD("scif1", 720, R8A7791_CLK_P), + DEF_MOD("scif0", 721, R8A7791_CLK_P), + DEF_MOD("du1", 723, R8A7791_CLK_ZX), + DEF_MOD("du0", 724, R8A7791_CLK_ZX), + DEF_MOD("lvds0", 726, R8A7791_CLK_ZX), + DEF_MOD("ipmmu-sgx", 800, R8A7791_CLK_ZX), + DEF_MOD("mlb", 802, R8A7791_CLK_HP), + DEF_MOD("vin2", 809, R8A7791_CLK_ZG), + DEF_MOD("vin1", 810, R8A7791_CLK_ZG), + DEF_MOD("vin0", 811, R8A7791_CLK_ZG), + DEF_MOD("etheravb", 812, R8A7791_CLK_HP), + DEF_MOD("ether", 813, R8A7791_CLK_P), + DEF_MOD("sata1", 814, R8A7791_CLK_ZS), + DEF_MOD("sata0", 815, R8A7791_CLK_ZS), + DEF_MOD("gyro-adc", 901, R8A7791_CLK_P), + DEF_MOD("gpio7", 904, R8A7791_CLK_CP), + DEF_MOD("gpio6", 905, R8A7791_CLK_CP), + DEF_MOD("gpio5", 907, R8A7791_CLK_CP), + DEF_MOD("gpio4", 908, R8A7791_CLK_CP), + DEF_MOD("gpio3", 909, R8A7791_CLK_CP), + DEF_MOD("gpio2", 910, R8A7791_CLK_CP), + DEF_MOD("gpio1", 911, R8A7791_CLK_CP), + DEF_MOD("gpio0", 912, R8A7791_CLK_CP), + DEF_MOD("can1", 915, R8A7791_CLK_P), + DEF_MOD("can0", 916, R8A7791_CLK_P), + DEF_MOD("qspi_mod", 917, R8A7791_CLK_QSPI), + DEF_MOD("i2c5", 925, R8A7791_CLK_HP), + DEF_MOD("iicdvfs", 926, R8A7791_CLK_CP), + DEF_MOD("i2c4", 927, R8A7791_CLK_HP), + DEF_MOD("i2c3", 928, R8A7791_CLK_HP), + DEF_MOD("i2c2", 929, R8A7791_CLK_HP), + DEF_MOD("i2c1", 930, R8A7791_CLK_HP), + DEF_MOD("i2c0", 931, R8A7791_CLK_HP), + DEF_MOD("ssi-all", 1005, R8A7791_CLK_P), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A7791_CLK_P), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), + DEF_MOD("scifa3", 1106, R8A7791_CLK_MP), + DEF_MOD("scifa4", 1107, R8A7791_CLK_MP), + DEF_MOD("scifa5", 1108, R8A7791_CLK_MP), +}; + +static const unsigned int r8a7791_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-SYS (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x172/2 x208/2 x106 + * 0 0 1 15 x172/2 x208/2 x88 + * 0 1 0 20 x130/2 x156/2 x80 + * 0 1 1 20 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.5a indicates VCO output (PLLx = VCO/2) + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ + (((md) & BIT(13)) >> 12) | \ + (((md) & BIT(19)) >> 19)) +static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = { + { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 }, + { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 }, +}; + +static int __init r8a7791_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen2_cpg_pll_config *cpg_pll_config; + struct device_node *np = dev->of_node; + unsigned int i; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + if (of_device_is_compatible(np, "renesas,r8a7793-cpg-mssr")) { + /* R-Car M2-N uses a 1/5 divider for ZG */ + for (i = 0; i < ARRAY_SIZE(r8a7791_core_clks); i++) + if (r8a7791_core_clks[i].id == R8A7791_CLK_ZG) { + r8a7791_core_clks[i].div = 5; + break; + } + } + return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode); +} + +const struct cpg_mssr_info r8a7791_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7791_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7791_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7791_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7791_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7791_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7791_crit_mod_clks), + + /* Callbacks */ + .init = r8a7791_cpg_mssr_init, + .cpg_clk_register = rcar_gen2_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c new file mode 100644 index 000000000000..a832b9b6f7b0 --- /dev/null +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c @@ -0,0 +1,221 @@ +/* + * r8a7792 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2017 Glider bvba + * + * Based on clk-rcar-gen2.c + * + * Copyright (C) 2013 Ideas On Board SPRL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/soc/renesas/rcar-rst.h> + +#include <dt-bindings/clock/r8a7792-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen2-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7792_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL1_DIV2, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a7792_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_BASE("lb", R8A7792_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), + DEF_BASE("qspi", R8A7792_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), + + DEF_FIXED("z", R8A7792_CLK_Z, CLK_PLL0, 1, 1), + DEF_FIXED("zg", R8A7792_CLK_ZG, CLK_PLL1, 5, 1), + DEF_FIXED("zx", R8A7792_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("zs", R8A7792_CLK_ZS, CLK_PLL1, 6, 1), + DEF_FIXED("hp", R8A7792_CLK_HP, CLK_PLL1, 12, 1), + DEF_FIXED("i", R8A7792_CLK_I, CLK_PLL1, 3, 1), + DEF_FIXED("b", R8A7792_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("p", R8A7792_CLK_P, CLK_PLL1, 24, 1), + DEF_FIXED("cl", R8A7792_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("m2", R8A7792_CLK_M2, CLK_PLL1, 8, 1), + DEF_FIXED("imp", R8A7792_CLK_IMP, CLK_PLL1, 4, 1), + DEF_FIXED("zb3", R8A7792_CLK_ZB3, CLK_PLL3, 4, 1), + DEF_FIXED("zb3d2", R8A7792_CLK_ZB3D2, CLK_PLL3, 8, 1), + DEF_FIXED("ddr", R8A7792_CLK_DDR, CLK_PLL3, 8, 1), + DEF_FIXED("sd", R8A7792_CLK_SD, CLK_PLL1_DIV2, 8, 1), + DEF_FIXED("mp", R8A7792_CLK_MP, CLK_PLL1_DIV2, 15, 1), + DEF_FIXED("cp", R8A7792_CLK_CP, CLK_PLL1, 48, 1), + DEF_FIXED("cpex", R8A7792_CLK_CPEX, CLK_EXTAL, 2, 1), + DEF_FIXED("rcan", R8A7792_CLK_RCAN, CLK_PLL1_DIV2, 49, 1), + DEF_FIXED("r", R8A7792_CLK_R, CLK_PLL1, 49152, 1), + DEF_FIXED("osc", R8A7792_CLK_OSC, CLK_PLL1, 12288, 1), +}; + +static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = { + DEF_MOD("msiof0", 0, R8A7792_CLK_MP), + DEF_MOD("jpu", 106, R8A7792_CLK_M2), + DEF_MOD("tmu1", 111, R8A7792_CLK_P), + DEF_MOD("3dg", 112, R8A7792_CLK_ZG), + DEF_MOD("2d-dmac", 115, R8A7792_CLK_ZS), + DEF_MOD("tmu3", 121, R8A7792_CLK_P), + DEF_MOD("tmu2", 122, R8A7792_CLK_P), + DEF_MOD("cmt0", 124, R8A7792_CLK_R), + DEF_MOD("tmu0", 125, R8A7792_CLK_CP), + DEF_MOD("vsp1du1", 127, R8A7792_CLK_ZS), + DEF_MOD("vsp1du0", 128, R8A7792_CLK_ZS), + DEF_MOD("vsp1-sy", 131, R8A7792_CLK_ZS), + DEF_MOD("msiof1", 208, R8A7792_CLK_MP), + DEF_MOD("sys-dmac1", 218, R8A7792_CLK_ZS), + DEF_MOD("sys-dmac0", 219, R8A7792_CLK_ZS), + DEF_MOD("tpu0", 304, R8A7792_CLK_CP), + DEF_MOD("sdhi0", 314, R8A7792_CLK_SD), + DEF_MOD("cmt1", 329, R8A7792_CLK_R), + DEF_MOD("irqc", 407, R8A7792_CLK_CP), + DEF_MOD("intc-sys", 408, R8A7792_CLK_ZS), + DEF_MOD("audio-dmac0", 502, R8A7792_CLK_HP), + DEF_MOD("thermal", 522, CLK_EXTAL), + DEF_MOD("pwm", 523, R8A7792_CLK_P), + DEF_MOD("hscif1", 716, R8A7792_CLK_ZS), + DEF_MOD("hscif0", 717, R8A7792_CLK_ZS), + DEF_MOD("scif3", 718, R8A7792_CLK_P), + DEF_MOD("scif2", 719, R8A7792_CLK_P), + DEF_MOD("scif1", 720, R8A7792_CLK_P), + DEF_MOD("scif0", 721, R8A7792_CLK_P), + DEF_MOD("du1", 723, R8A7792_CLK_ZX), + DEF_MOD("du0", 724, R8A7792_CLK_ZX), + DEF_MOD("vin5", 804, R8A7792_CLK_ZG), + DEF_MOD("vin4", 805, R8A7792_CLK_ZG), + DEF_MOD("vin3", 808, R8A7792_CLK_ZG), + DEF_MOD("vin2", 809, R8A7792_CLK_ZG), + DEF_MOD("vin1", 810, R8A7792_CLK_ZG), + DEF_MOD("vin0", 811, R8A7792_CLK_ZG), + DEF_MOD("etheravb", 812, R8A7792_CLK_HP), + DEF_MOD("gyro-adc", 901, R8A7792_CLK_P), + DEF_MOD("gpio7", 904, R8A7792_CLK_CP), + DEF_MOD("gpio6", 905, R8A7792_CLK_CP), + DEF_MOD("gpio5", 907, R8A7792_CLK_CP), + DEF_MOD("gpio4", 908, R8A7792_CLK_CP), + DEF_MOD("gpio3", 909, R8A7792_CLK_CP), + DEF_MOD("gpio2", 910, R8A7792_CLK_CP), + DEF_MOD("gpio1", 911, R8A7792_CLK_CP), + DEF_MOD("gpio0", 912, R8A7792_CLK_CP), + DEF_MOD("gpio11", 913, R8A7792_CLK_CP), + DEF_MOD("gpio10", 914, R8A7792_CLK_CP), + DEF_MOD("can1", 915, R8A7792_CLK_P), + DEF_MOD("can0", 916, R8A7792_CLK_P), + DEF_MOD("qspi_mod", 917, R8A7792_CLK_QSPI), + DEF_MOD("gpio9", 919, R8A7792_CLK_CP), + DEF_MOD("gpio8", 921, R8A7792_CLK_CP), + DEF_MOD("i2c5", 925, R8A7792_CLK_HP), + DEF_MOD("iicdvfs", 926, R8A7792_CLK_CP), + DEF_MOD("i2c4", 927, R8A7792_CLK_HP), + DEF_MOD("i2c3", 928, R8A7792_CLK_HP), + DEF_MOD("i2c2", 929, R8A7792_CLK_HP), + DEF_MOD("i2c1", 930, R8A7792_CLK_HP), + DEF_MOD("i2c0", 931, R8A7792_CLK_HP), + DEF_MOD("ssi-all", 1005, R8A7792_CLK_P), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), +}; + +static const unsigned int r8a7792_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-SYS (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *2 + *--------------------------------------------------- + * 0 0 0 15 x200/3 x208/2 x106 + * 0 0 1 15 x200/3 x208/2 x88 + * 0 1 0 20 x150/3 x156/2 x80 + * 0 1 1 20 x150/3 x156/2 x66 + * 1 0 0 26 / 2 x230/3 x240/2 x122 + * 1 0 1 26 / 2 x230/3 x240/2 x102 + * 1 1 0 30 / 2 x200/3 x208/2 x106 + * 1 1 1 30 / 2 x200/3 x208/2 x88 + * + * *1 : Table 7.5b indicates VCO output (PLL0 = VCO/3) + * *2 : Table 7.5b indicates VCO output (PLL1 = VCO/2) + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ + (((md) & BIT(13)) >> 12) | \ + (((md) & BIT(19)) >> 19)) +static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = { + { 1, 208, 106, 200 }, + { 1, 208, 88, 200 }, + { 1, 156, 80, 150 }, + { 1, 156, 66, 150 }, + { 2, 240, 122, 230 }, + { 2, 240, 102, 230 }, + { 2, 208, 106, 200 }, + { 2, 208, 88, 200 }, +}; + +static int __init r8a7792_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen2_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen2_cpg_init(cpg_pll_config, 3, cpg_mode); +} + +const struct cpg_mssr_info r8a7792_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7792_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7792_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7792_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7792_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7792_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7792_crit_mod_clks), + + /* Callbacks */ + .init = r8a7792_cpg_mssr_init, + .cpg_clk_register = rcar_gen2_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c new file mode 100644 index 000000000000..ec091a42da54 --- /dev/null +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c @@ -0,0 +1,255 @@ +/* + * r8a7794 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2017 Glider bvba + * + * Based on clk-rcar-gen2.c + * + * Copyright (C) 2013 Ideas On Board SPRL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/soc/renesas/rcar-rst.h> + +#include <dt-bindings/clock/r8a7794-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen2-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7794_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_USB_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL1_DIV2, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a7794_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("usb_extal", CLK_USB_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_BASE("lb", R8A7794_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), + DEF_BASE("adsp", R8A7794_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1), + DEF_BASE("sdh", R8A7794_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), + DEF_BASE("sd0", R8A7794_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), + DEF_BASE("qspi", R8A7794_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), + DEF_BASE("rcan", R8A7794_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL), + + DEF_FIXED("z2", R8A7794_CLK_Z2, CLK_PLL0, 1, 1), + DEF_FIXED("zg", R8A7794_CLK_ZG, CLK_PLL1, 6, 1), + DEF_FIXED("zx", R8A7794_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("zs", R8A7794_CLK_ZS, CLK_PLL1, 6, 1), + DEF_FIXED("hp", R8A7794_CLK_HP, CLK_PLL1, 12, 1), + DEF_FIXED("i", R8A7794_CLK_I, CLK_PLL1, 2, 1), + DEF_FIXED("b", R8A7794_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("p", R8A7794_CLK_P, CLK_PLL1, 24, 1), + DEF_FIXED("cl", R8A7794_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A7794_CLK_CP, CLK_PLL1, 48, 1), + DEF_FIXED("m2", R8A7794_CLK_M2, CLK_PLL1, 8, 1), + DEF_FIXED("zb3", R8A7794_CLK_ZB3, CLK_PLL3, 4, 1), + DEF_FIXED("zb3d2", R8A7794_CLK_ZB3D2, CLK_PLL3, 8, 1), + DEF_FIXED("ddr", R8A7794_CLK_DDR, CLK_PLL3, 8, 1), + DEF_FIXED("mp", R8A7794_CLK_MP, CLK_PLL1_DIV2, 15, 1), + DEF_FIXED("cpex", R8A7794_CLK_CPEX, CLK_EXTAL, 2, 1), + DEF_FIXED("r", R8A7794_CLK_R, CLK_PLL1, 49152, 1), + DEF_FIXED("osc", R8A7794_CLK_OSC, CLK_PLL1, 12288, 1), + + DEF_DIV6P1("sd2", R8A7794_CLK_SD2, CLK_PLL1_DIV2, 0x078), + DEF_DIV6P1("sd3", R8A7794_CLK_SD3, CLK_PLL1_DIV2, 0x26c), + DEF_DIV6P1("mmc0", R8A7794_CLK_MMC0, CLK_PLL1_DIV2, 0x240), +}; + +static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { + DEF_MOD("msiof0", 0, R8A7794_CLK_MP), + DEF_MOD("vcp0", 101, R8A7794_CLK_ZS), + DEF_MOD("vpc0", 103, R8A7794_CLK_ZS), + DEF_MOD("jpu", 106, R8A7794_CLK_M2), + DEF_MOD("tmu1", 111, R8A7794_CLK_P), + DEF_MOD("3dg", 112, R8A7794_CLK_ZG), + DEF_MOD("2d-dmac", 115, R8A7794_CLK_ZS), + DEF_MOD("fdp1-0", 119, R8A7794_CLK_ZS), + DEF_MOD("tmu3", 121, R8A7794_CLK_P), + DEF_MOD("tmu2", 122, R8A7794_CLK_P), + DEF_MOD("cmt0", 124, R8A7794_CLK_R), + DEF_MOD("tmu0", 125, R8A7794_CLK_CP), + DEF_MOD("vsp1du0", 128, R8A7794_CLK_ZS), + DEF_MOD("vsp1-sy", 131, R8A7794_CLK_ZS), + DEF_MOD("scifa2", 202, R8A7794_CLK_MP), + DEF_MOD("scifa1", 203, R8A7794_CLK_MP), + DEF_MOD("scifa0", 204, R8A7794_CLK_MP), + DEF_MOD("msiof2", 205, R8A7794_CLK_MP), + DEF_MOD("scifb0", 206, R8A7794_CLK_MP), + DEF_MOD("scifb1", 207, R8A7794_CLK_MP), + DEF_MOD("msiof1", 208, R8A7794_CLK_MP), + DEF_MOD("scifb2", 216, R8A7794_CLK_MP), + DEF_MOD("sys-dmac1", 218, R8A7794_CLK_ZS), + DEF_MOD("sys-dmac0", 219, R8A7794_CLK_ZS), + DEF_MOD("tpu0", 304, R8A7794_CLK_CP), + DEF_MOD("sdhi3", 311, R8A7794_CLK_SD3), + DEF_MOD("sdhi2", 312, R8A7794_CLK_SD2), + DEF_MOD("sdhi0", 314, R8A7794_CLK_SD0), + DEF_MOD("mmcif0", 315, R8A7794_CLK_MMC0), + DEF_MOD("iic0", 318, R8A7794_CLK_HP), + DEF_MOD("iic1", 323, R8A7794_CLK_HP), + DEF_MOD("cmt1", 329, R8A7794_CLK_R), + DEF_MOD("usbhs-dmac0", 330, R8A7794_CLK_HP), + DEF_MOD("usbhs-dmac1", 331, R8A7794_CLK_HP), + DEF_MOD("irqc", 407, R8A7794_CLK_CP), + DEF_MOD("intc-sys", 408, R8A7794_CLK_ZS), + DEF_MOD("audio-dmac0", 502, R8A7794_CLK_HP), + DEF_MOD("adsp_mod", 506, R8A7794_CLK_ADSP), + DEF_MOD("pwm", 523, R8A7794_CLK_P), + DEF_MOD("usb-ehci", 703, R8A7794_CLK_MP), + DEF_MOD("usbhs", 704, R8A7794_CLK_HP), + DEF_MOD("hscif2", 713, R8A7794_CLK_ZS), + DEF_MOD("scif5", 714, R8A7794_CLK_P), + DEF_MOD("scif4", 715, R8A7794_CLK_P), + DEF_MOD("hscif1", 716, R8A7794_CLK_ZS), + DEF_MOD("hscif0", 717, R8A7794_CLK_ZS), + DEF_MOD("scif3", 718, R8A7794_CLK_P), + DEF_MOD("scif2", 719, R8A7794_CLK_P), + DEF_MOD("scif1", 720, R8A7794_CLK_P), + DEF_MOD("scif0", 721, R8A7794_CLK_P), + DEF_MOD("du1", 723, R8A7794_CLK_ZX), + DEF_MOD("du0", 724, R8A7794_CLK_ZX), + DEF_MOD("ipmmu-sgx", 800, R8A7794_CLK_ZX), + DEF_MOD("mlb", 802, R8A7794_CLK_HP), + DEF_MOD("vin1", 810, R8A7794_CLK_ZG), + DEF_MOD("vin0", 811, R8A7794_CLK_ZG), + DEF_MOD("etheravb", 812, R8A7794_CLK_HP), + DEF_MOD("ether", 813, R8A7794_CLK_P), + DEF_MOD("gyro-adc", 901, R8A7794_CLK_P), + DEF_MOD("gpio6", 905, R8A7794_CLK_CP), + DEF_MOD("gpio5", 907, R8A7794_CLK_CP), + DEF_MOD("gpio4", 908, R8A7794_CLK_CP), + DEF_MOD("gpio3", 909, R8A7794_CLK_CP), + DEF_MOD("gpio2", 910, R8A7794_CLK_CP), + DEF_MOD("gpio1", 911, R8A7794_CLK_CP), + DEF_MOD("gpio0", 912, R8A7794_CLK_CP), + DEF_MOD("can1", 915, R8A7794_CLK_P), + DEF_MOD("can0", 916, R8A7794_CLK_P), + DEF_MOD("qspi_mod", 917, R8A7794_CLK_QSPI), + DEF_MOD("i2c5", 925, R8A7794_CLK_HP), + DEF_MOD("i2c4", 927, R8A7794_CLK_HP), + DEF_MOD("i2c3", 928, R8A7794_CLK_HP), + DEF_MOD("i2c2", 929, R8A7794_CLK_HP), + DEF_MOD("i2c1", 930, R8A7794_CLK_HP), + DEF_MOD("i2c0", 931, R8A7794_CLK_HP), + DEF_MOD("ssi-all", 1005, R8A7794_CLK_P), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A7794_CLK_P), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scifa3", 1106, R8A7794_CLK_MP), + DEF_MOD("scifa4", 1107, R8A7794_CLK_MP), + DEF_MOD("scifa5", 1108, R8A7794_CLK_MP), +}; + +static const unsigned int r8a7794_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-SYS (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *2 + *--------------------------------------------------- + * 0 0 1 15 x200/3 x208/2 x88 + * 0 1 1 20 x150/3 x156/2 x66 + * 1 0 1 26 / 2 x230/3 x240/2 x102 + * 1 1 1 30 / 2 x200/3 x208/2 x88 + * + * *1 : Table 7.5c indicates VCO output (PLL0 = VCO/3) + * *2 : Table 7.5c indicates VCO output (PLL1 = VCO/2) + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \ + (((md) & BIT(13)) >> 13)) +static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[4] __initconst = { + { 1, 208, 88, 200 }, + { 1, 156, 66, 150 }, + { 2, 240, 102, 230 }, + { 2, 208, 88, 200 }, +}; + +static int __init r8a7794_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen2_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen2_cpg_init(cpg_pll_config, 3, cpg_mode); +} + +const struct cpg_mssr_info r8a7794_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7794_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7794_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7794_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7794_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7794_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7794_crit_mod_clks), + + /* Callbacks */ + .init = r8a7794_cpg_mssr_init, + .cpg_clk_register = rcar_gen2_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index eaa98b488f01..c091a8e024b8 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -141,8 +141,10 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("sdif0", 314, R8A7795_CLK_SD0), DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac30", 326, R8A7795_CLK_S3D1), DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), /* ES1.x */ DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac31", 329, R8A7795_CLK_S3D1), DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), DEF_MOD("rwdt", 402, R8A7795_CLK_R), @@ -164,7 +166,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), DEF_MOD("thermal", 522, R8A7795_CLK_CP), - DEF_MOD("pwm", 523, R8A7795_CLK_S3D4), + DEF_MOD("pwm", 523, R8A7795_CLK_S0D12), DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1), /* ES1.x */ DEF_MOD("fcpvd2", 601, R8A7795_CLK_S0D2), DEF_MOD("fcpvd1", 602, R8A7795_CLK_S0D2), @@ -189,10 +191,12 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1), /* ES1.x */ DEF_MOD("vspi1", 630, R8A7795_CLK_S0D1), DEF_MOD("vspi0", 631, R8A7795_CLK_S0D1), + DEF_MOD("ehci3", 700, R8A7795_CLK_S3D4), DEF_MOD("ehci2", 701, R8A7795_CLK_S3D4), DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), + DEF_MOD("hsusb3", 705, R8A7795_CLK_S3D4), DEF_MOD("csi21", 713, R8A7795_CLK_CSI0), /* ES1.x */ DEF_MOD("csi20", 714, R8A7795_CLK_CSI0), DEF_MOD("csi41", 715, R8A7795_CLK_CSI0), @@ -218,22 +222,22 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("imr2", 821, R8A7795_CLK_S0D2), DEF_MOD("imr1", 822, R8A7795_CLK_S0D2), DEF_MOD("imr0", 823, R8A7795_CLK_S0D2), - DEF_MOD("gpio7", 905, R8A7795_CLK_CP), - DEF_MOD("gpio6", 906, R8A7795_CLK_CP), - DEF_MOD("gpio5", 907, R8A7795_CLK_CP), - DEF_MOD("gpio4", 908, R8A7795_CLK_CP), - DEF_MOD("gpio3", 909, R8A7795_CLK_CP), - DEF_MOD("gpio2", 910, R8A7795_CLK_CP), - DEF_MOD("gpio1", 911, R8A7795_CLK_CP), - DEF_MOD("gpio0", 912, R8A7795_CLK_CP), + DEF_MOD("gpio7", 905, R8A7795_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A7795_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A7795_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A7795_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A7795_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A7795_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A7795_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A7795_CLK_S3D4), 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("i2c6", 918, R8A7795_CLK_S3D2), - DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), + DEF_MOD("i2c6", 918, R8A7795_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A7795_CLK_S0D6), DEF_MOD("i2c-dvfs", 926, R8A7795_CLK_CP), - DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), - DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2), + DEF_MOD("i2c4", 927, R8A7795_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A7795_CLK_S0D6), DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2), DEF_MOD("i2c1", 930, R8A7795_CLK_S3D2), DEF_MOD("i2c0", 931, R8A7795_CLK_S3D2), @@ -346,6 +350,7 @@ static const struct mssr_mod_reparent r8a7795es1_mod_reparent[] __initconst = { { MOD_CLK_ID(219), R8A7795_CLK_S3D1 }, /* SYS-DMAC0 */ { MOD_CLK_ID(501), R8A7795_CLK_S3D1 }, /* AUDMAC1 */ { MOD_CLK_ID(502), R8A7795_CLK_S3D1 }, /* AUDMAC0 */ + { MOD_CLK_ID(523), R8A7795_CLK_S3D4 }, /* PWM */ { MOD_CLK_ID(601), R8A7795_CLK_S2D1 }, /* FCPVD2 */ { MOD_CLK_ID(602), R8A7795_CLK_S2D1 }, /* FCPVD1 */ { MOD_CLK_ID(603), R8A7795_CLK_S2D1 }, /* FCPVD0 */ @@ -376,6 +381,18 @@ static const struct mssr_mod_reparent r8a7795es1_mod_reparent[] __initconst = { { MOD_CLK_ID(821), R8A7795_CLK_S2D1 }, /* IMR2 */ { MOD_CLK_ID(822), R8A7795_CLK_S2D1 }, /* IMR1 */ { MOD_CLK_ID(823), R8A7795_CLK_S2D1 }, /* IMR0 */ + { MOD_CLK_ID(905), R8A7795_CLK_CP }, /* GPIO7 */ + { MOD_CLK_ID(906), R8A7795_CLK_CP }, /* GPIO6 */ + { MOD_CLK_ID(907), R8A7795_CLK_CP }, /* GPIO5 */ + { MOD_CLK_ID(908), R8A7795_CLK_CP }, /* GPIO4 */ + { MOD_CLK_ID(909), R8A7795_CLK_CP }, /* GPIO3 */ + { MOD_CLK_ID(910), R8A7795_CLK_CP }, /* GPIO2 */ + { MOD_CLK_ID(911), R8A7795_CLK_CP }, /* GPIO1 */ + { MOD_CLK_ID(912), R8A7795_CLK_CP }, /* GPIO0 */ + { MOD_CLK_ID(918), R8A7795_CLK_S3D2 }, /* I2C6 */ + { MOD_CLK_ID(919), R8A7795_CLK_S3D2 }, /* I2C5 */ + { MOD_CLK_ID(927), R8A7795_CLK_S3D2 }, /* I2C4 */ + { MOD_CLK_ID(928), R8A7795_CLK_S3D2 }, /* I2C3 */ }; diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 9d114b31b073..acc6d0f153e1 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -106,6 +106,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_DIV6P1("canfd", R8A7796_CLK_CANFD, CLK_PLL1_DIV4, 0x244), DEF_DIV6P1("csi0", R8A7796_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), DEF_DIV6P1("mso", R8A7796_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A7796_CLK_HDMI, CLK_PLL1_DIV4, 0x250), DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), @@ -135,8 +136,15 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("sdif2", 312, R8A7796_CLK_SD2), DEF_MOD("sdif1", 313, R8A7796_CLK_SD1), DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), + DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1), DEF_MOD("rwdt", 402, R8A7796_CLK_R), + DEF_MOD("intc-ex", 407, R8A7796_CLK_CP), DEF_MOD("intc-ap", 408, R8A7796_CLK_S3D1), + DEF_MOD("audmac1", 501, R8A7796_CLK_S0D3), + DEF_MOD("audmac0", 502, R8A7796_CLK_S0D3), DEF_MOD("drif7", 508, R8A7796_CLK_S3D2), DEF_MOD("drif6", 509, R8A7796_CLK_S3D2), DEF_MOD("drif5", 510, R8A7796_CLK_S3D2), @@ -151,6 +159,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("hscif1", 519, R8A7796_CLK_S3D1), DEF_MOD("hscif0", 520, R8A7796_CLK_S3D1), DEF_MOD("thermal", 522, R8A7796_CLK_CP), + DEF_MOD("pwm", 523, R8A7796_CLK_S0D12), DEF_MOD("fcpvd2", 601, R8A7796_CLK_S0D2), DEF_MOD("fcpvd1", 602, R8A7796_CLK_S0D2), DEF_MOD("fcpvd0", 603, R8A7796_CLK_S0D2), @@ -164,12 +173,16 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("vspd0", 623, R8A7796_CLK_S0D2), DEF_MOD("vspb", 626, R8A7796_CLK_S0D1), DEF_MOD("vspi0", 631, R8A7796_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A7796_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A7796_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A7796_CLK_S3D4), DEF_MOD("csi20", 714, R8A7796_CLK_CSI0), DEF_MOD("csi40", 716, R8A7796_CLK_CSI0), DEF_MOD("du2", 722, R8A7796_CLK_S2D1), DEF_MOD("du1", 723, R8A7796_CLK_S2D1), DEF_MOD("du0", 724, R8A7796_CLK_S2D1), DEF_MOD("lvds", 727, R8A7796_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A7796_CLK_HDMI), DEF_MOD("vin7", 804, R8A7796_CLK_S0D2), DEF_MOD("vin6", 805, R8A7796_CLK_S0D2), DEF_MOD("vin5", 806, R8A7796_CLK_S0D2), @@ -200,6 +213,32 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("i2c2", 929, R8A7796_CLK_S3D2), DEF_MOD("i2c1", 930, R8A7796_CLK_S3D2), DEF_MOD("i2c0", 931, R8A7796_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A7796_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A7796_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), }; static const unsigned int r8a7796_crit_mod_clks[] __initconst = { diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 99eeec6f24ec..f44a8125615b 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -257,7 +257,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, const struct cpg_mssr_info *info, struct cpg_mssr_priv *priv) { - struct clk *clk = NULL, *parent; + struct clk *clk = ERR_PTR(-ENOTSUPP), *parent; struct device *dev = priv->dev; unsigned int id = core->id, div = core->div; const char *parent_name; @@ -477,7 +477,7 @@ fail_put: void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev) { - if (!list_empty(&dev->power.subsys_data->clock_list)) + if (!pm_clk_no_clocks(dev)) pm_clk_destroy(dev); } @@ -627,25 +627,54 @@ static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv) static const struct of_device_id cpg_mssr_match[] = { -#ifdef CONFIG_ARCH_R8A7743 +#ifdef CONFIG_CLK_R8A7743 { .compatible = "renesas,r8a7743-cpg-mssr", .data = &r8a7743_cpg_mssr_info, }, #endif -#ifdef CONFIG_ARCH_R8A7745 +#ifdef CONFIG_CLK_R8A7745 { .compatible = "renesas,r8a7745-cpg-mssr", .data = &r8a7745_cpg_mssr_info, }, #endif -#ifdef CONFIG_ARCH_R8A7795 +#ifdef CONFIG_CLK_R8A7790 + { + .compatible = "renesas,r8a7790-cpg-mssr", + .data = &r8a7790_cpg_mssr_info, + }, +#endif +#ifdef CONFIG_CLK_R8A7791 + { + .compatible = "renesas,r8a7791-cpg-mssr", + .data = &r8a7791_cpg_mssr_info, + }, + /* R-Car M2-N is (almost) identical to R-Car M2-W w.r.t. clocks. */ + { + .compatible = "renesas,r8a7793-cpg-mssr", + .data = &r8a7791_cpg_mssr_info, + }, +#endif +#ifdef CONFIG_CLK_R8A7792 + { + .compatible = "renesas,r8a7792-cpg-mssr", + .data = &r8a7792_cpg_mssr_info, + }, +#endif +#ifdef CONFIG_CLK_R8A7794 + { + .compatible = "renesas,r8a7794-cpg-mssr", + .data = &r8a7794_cpg_mssr_info, + }, +#endif +#ifdef CONFIG_CLK_R8A7795 { .compatible = "renesas,r8a7795-cpg-mssr", .data = &r8a7795_cpg_mssr_info, }, #endif -#ifdef CONFIG_ARCH_R8A7796 +#ifdef CONFIG_CLK_R8A7796 { .compatible = "renesas,r8a7796-cpg-mssr", .data = &r8a7796_cpg_mssr_info, diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 148f4f0aa2a4..43d7c7f6832d 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -132,6 +132,10 @@ struct cpg_mssr_info { extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; +extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; +extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; +extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; +extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 26b220c988b2..6f19826cc447 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-y += clk-rv1108.o obj-y += clk-rk3036.o +obj-y += clk-rk3128.o obj-y += clk-rk3188.o obj-y += clk-rk3228.o obj-y += clk-rk3288.o diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 00d4150e33c3..c3001980dbdc 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -436,6 +436,7 @@ static const char *const rk3036_critical_clocks[] __initconst = { "aclk_peri", "hclk_peri", "pclk_peri", + "pclk_ddrupctl", }; static void __init rk3036_clk_init(struct device_node *np) diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c new file mode 100644 index 000000000000..e243f2eae68f --- /dev/null +++ b/drivers/clk/rockchip/clk-rk3128.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2017 Rockchip Electronics Co. Ltd. + * Author: Elaine <zhangqing@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/syscore_ops.h> +#include <dt-bindings/clock/rk3128-cru.h> +#include "clk.h" + +#define RK3128_GRF_SOC_STATUS0 0x14c + +enum rk3128_plls { + apll, dpll, cpll, gpll, +}; + +static struct rockchip_pll_rate_table rk3128_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), + RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), + RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0), + RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0), + RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0), + RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0), + RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0), + RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0), + RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), + RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), + RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), + RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0), + RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0), + RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0), + RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0), + RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0), + RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0), + RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), + RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0), + RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0), + { /* sentinel */ }, +}; + +#define RK3128_DIV_CPU_MASK 0x1f +#define RK3128_DIV_CPU_SHIFT 8 + +#define RK3128_DIV_PERI_MASK 0xf +#define RK3128_DIV_PERI_SHIFT 0 +#define RK3128_DIV_ACLK_MASK 0x7 +#define RK3128_DIV_ACLK_SHIFT 4 +#define RK3128_DIV_HCLK_MASK 0x3 +#define RK3128_DIV_HCLK_SHIFT 8 +#define RK3128_DIV_PCLK_MASK 0x7 +#define RK3128_DIV_PCLK_SHIFT 12 + +#define RK3128_CLKSEL1(_core_aclk_div, _pclk_dbg_div) \ +{ \ + .reg = RK2928_CLKSEL_CON(1), \ + .val = HIWORD_UPDATE(_pclk_dbg_div, RK3128_DIV_PERI_MASK, \ + RK3128_DIV_PERI_SHIFT) | \ + HIWORD_UPDATE(_core_aclk_div, RK3128_DIV_ACLK_MASK, \ + RK3128_DIV_ACLK_SHIFT), \ +} + +#define RK3128_CPUCLK_RATE(_prate, _core_aclk_div, _pclk_dbg_div) \ +{ \ + .prate = _prate, \ + .divs = { \ + RK3128_CLKSEL1(_core_aclk_div, _pclk_dbg_div), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rk3128_cpuclk_rates[] __initdata = { + RK3128_CPUCLK_RATE(1800000000, 1, 7), + RK3128_CPUCLK_RATE(1704000000, 1, 7), + RK3128_CPUCLK_RATE(1608000000, 1, 7), + RK3128_CPUCLK_RATE(1512000000, 1, 7), + RK3128_CPUCLK_RATE(1488000000, 1, 5), + RK3128_CPUCLK_RATE(1416000000, 1, 5), + RK3128_CPUCLK_RATE(1392000000, 1, 5), + RK3128_CPUCLK_RATE(1296000000, 1, 5), + RK3128_CPUCLK_RATE(1200000000, 1, 5), + RK3128_CPUCLK_RATE(1104000000, 1, 5), + RK3128_CPUCLK_RATE(1008000000, 1, 5), + RK3128_CPUCLK_RATE(912000000, 1, 5), + RK3128_CPUCLK_RATE(816000000, 1, 3), + RK3128_CPUCLK_RATE(696000000, 1, 3), + RK3128_CPUCLK_RATE(600000000, 1, 3), + RK3128_CPUCLK_RATE(408000000, 1, 1), + RK3128_CPUCLK_RATE(312000000, 1, 1), + RK3128_CPUCLK_RATE(216000000, 1, 1), + RK3128_CPUCLK_RATE(96000000, 1, 1), +}; + +static const struct rockchip_cpuclk_reg_data rk3128_cpuclk_data = { + .core_reg = RK2928_CLKSEL_CON(0), + .div_core_shift = 0, + .div_core_mask = 0x1f, + .mux_core_alt = 1, + .mux_core_main = 0, + .mux_core_shift = 7, + .mux_core_mask = 0x1, +}; + +PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; + +PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_div2_ddr" }; +PNAME(mux_armclk_p) = { "apll_core", "gpll_div2_core" }; +PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" }; +PNAME(mux_aclk_cpu_src_p) = { "cpll", "gpll", "gpll_div2", "gpll_div3" }; + +PNAME(mux_pll_src_5plls_p) = { "cpll", "gpll", "gpll_div2", "gpll_div3", "usb480m" }; +PNAME(mux_pll_src_4plls_p) = { "cpll", "gpll", "gpll_div2", "usb480m" }; +PNAME(mux_pll_src_3plls_p) = { "cpll", "gpll", "gpll_div2" }; + +PNAME(mux_aclk_peri_src_p) = { "gpll_peri", "cpll_peri", "gpll_div2_peri", "gpll_div3_peri" }; +PNAME(mux_mmc_src_p) = { "cpll", "gpll", "gpll_div2", "xin24m" }; +PNAME(mux_clk_cif_out_src_p) = { "clk_cif_src", "xin24m" }; +PNAME(mux_sclk_vop_src_p) = { "cpll", "gpll", "gpll_div2", "gpll_div3" }; + +PNAME(mux_i2s0_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; +PNAME(mux_i2s1_pre_p) = { "i2s1_src", "i2s1_frac", "ext_i2s", "xin12m" }; +PNAME(mux_i2s_out_p) = { "i2s1_pre", "xin12m" }; +PNAME(mux_sclk_spdif_p) = { "sclk_spdif_src", "spdif_frac", "xin12m" }; + +PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; +PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; +PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; + +PNAME(mux_sclk_gmac_p) = { "sclk_gmac_src", "gmac_clkin" }; +PNAME(mux_sclk_sfc_src_p) = { "cpll", "gpll", "gpll_div2", "xin24m" }; + +static struct rockchip_pll_clock rk3128_pll_clks[] __initdata = { + [apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), + RK2928_MODE_CON, 0, 1, 0, rk3128_pll_rates), + [dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), + RK2928_MODE_CON, 4, 0, 0, NULL), + [cpll] = PLL(pll_rk3036, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), + RK2928_MODE_CON, 8, 2, 0, rk3128_pll_rates), + [gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), + RK2928_MODE_CON, 12, 3, ROCKCHIP_PLL_SYNC_RATE, rk3128_pll_rates), +}; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_clk_branch rk3128_i2s0_fracmux __initdata = + MUX(0, "i2s0_pre", mux_i2s0_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(9), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3128_i2s1_fracmux __initdata = + MUX(0, "i2s1_pre", mux_i2s1_pre_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3128_spdif_fracmux __initdata = + MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(6), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3128_uart0_fracmux __initdata = + MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(13), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3128_uart1_fracmux __initdata = + MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(14), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3128_uart2_fracmux __initdata = + MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { + /* + * Clock-Architecture Diagram 1 + */ + + FACTOR(PLL_GPLL_DIV2, "gpll_div2", "gpll", 0, 1, 2), + FACTOR(PLL_GPLL_DIV3, "gpll_div3", "gpll", 0, 1, 3), + + DIV(0, "clk_24m", "xin24m", CLK_IGNORE_UNUSED, + RK2928_CLKSEL_CON(4), 8, 5, DFLAGS), + + /* PD_DDR */ + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(0), 2, GFLAGS), + GATE(0, "gpll_div2_ddr", "gpll_div2", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED, + RK2928_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), + FACTOR(SCLK_DDRC, "clk_ddrc", "ddrphy2x", 0, 1, 2), + FACTOR(0, "clk_ddrphy", "ddrphy2x", 0, 1, 2), + + /* PD_CORE */ + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(0), 6, GFLAGS), + GATE(0, "gpll_div2_core", "gpll_div2", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, + RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK2928_CLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NOMUX(0, "armcore", "armclk", CLK_IGNORE_UNUSED, + RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK2928_CLKGATE_CON(0), 7, GFLAGS), + + /* PD_MISC */ + MUX(SCLK_USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT, + RK2928_MISC_CON, 15, 1, MFLAGS), + + /* PD_CPU */ + COMPOSITE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, + RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(0), 1, GFLAGS), + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, + RK2928_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0, + RK2928_CLKSEL_CON(1), 8, 2, DFLAGS, + RK2928_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_src", 0, + RK2928_CLKSEL_CON(1), 12, 2, DFLAGS, + RK2928_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX(SCLK_CRYPTO, "clk_crypto", "aclk_cpu_src", 0, + RK2928_CLKSEL_CON(24), 0, 2, DFLAGS, + RK2928_CLKGATE_CON(0), 12, GFLAGS), + + /* PD_VIDEO */ + COMPOSITE(ACLK_VEPU, "aclk_vepu", mux_pll_src_5plls_p, 0, + RK2928_CLKSEL_CON(32), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(3), 9, GFLAGS), + FACTOR(HCLK_VEPU, "hclk_vepu", "aclk_vepu", 0, 1, 4), + + COMPOSITE(ACLK_VDPU, "aclk_vdpu", mux_pll_src_5plls_p, 0, + RK2928_CLKSEL_CON(32), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(3), 11, GFLAGS), + FACTOR_GATE(HCLK_VDPU, "hclk_vdpu", "aclk_vdpu", 0, 1, 4, + RK2928_CLKGATE_CON(3), 12, GFLAGS), + + COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_5plls_p, 0, + RK2928_CLKSEL_CON(34), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(3), 10, GFLAGS), + + /* PD_VIO */ + COMPOSITE(ACLK_VIO0, "aclk_vio0", mux_pll_src_5plls_p, 0, + RK2928_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(3), 0, GFLAGS), + COMPOSITE(ACLK_VIO1, "aclk_vio1", mux_pll_src_5plls_p, 0, + RK2928_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(1), 4, GFLAGS), + COMPOSITE(HCLK_VIO, "hclk_vio", mux_pll_src_4plls_p, 0, + RK2928_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(0), 11, GFLAGS), + + /* PD_PERI */ + GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(2), 0, GFLAGS), + GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(2), 0, GFLAGS), + GATE(0, "gpll_div2_peri", "gpll_div2", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(2), 0, GFLAGS), + GATE(0, "gpll_div3_peri", "gpll_div3", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(2), 0, GFLAGS), + COMPOSITE_NOGATE(0, "aclk_peri_src", mux_aclk_peri_src_p, 0, + RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS), + COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, + RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, + RK2928_CLKGATE_CON(2), 3, GFLAGS), + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, + RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, + RK2928_CLKGATE_CON(2), 2, GFLAGS), + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, + RK2928_CLKGATE_CON(2), 1, GFLAGS), + + GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, + RK2928_CLKGATE_CON(10), 3, GFLAGS), + GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, + RK2928_CLKGATE_CON(10), 4, GFLAGS), + GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, + RK2928_CLKGATE_CON(10), 5, GFLAGS), + GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, + RK2928_CLKGATE_CON(10), 6, GFLAGS), + GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, + RK2928_CLKGATE_CON(10), 7, GFLAGS), + GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, + RK2928_CLKGATE_CON(10), 8, GFLAGS), + + GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0, + RK2928_CLKGATE_CON(10), 8, GFLAGS), + GATE(SCLK_PVTM_GPU, "clk_pvtm_gpu", "xin24m", 0, + RK2928_CLKGATE_CON(10), 8, GFLAGS), + GATE(SCLK_PVTM_FUNC, "clk_pvtm_func", "xin24m", 0, + RK2928_CLKGATE_CON(10), 8, GFLAGS), + GATE(SCLK_MIPI_24M, "clk_mipi_24m", "xin24m", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(10), 8, GFLAGS), + + COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, + RK2928_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK2928_CLKGATE_CON(2), 11, GFLAGS), + + COMPOSITE(SCLK_SDIO, "sclk_sdio", mux_mmc_src_p, 0, + RK2928_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK2928_CLKGATE_CON(2), 13, GFLAGS), + + COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0, + RK2928_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK2928_CLKGATE_CON(2), 14, GFLAGS), + + DIV(SCLK_PVTM, "clk_pvtm", "clk_pvtm_func", 0, + RK2928_CLKSEL_CON(2), 0, 7, DFLAGS), + + /* + * Clock-Architecture Diagram 2 + */ + COMPOSITE(DCLK_VOP, "dclk_vop", mux_sclk_vop_src_p, 0, + RK2928_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, + RK2928_CLKGATE_CON(3), 1, GFLAGS), + COMPOSITE(SCLK_VOP, "sclk_vop", mux_sclk_vop_src_p, 0, + RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS, + RK2928_CLKGATE_CON(3), 2, GFLAGS), + COMPOSITE(DCLK_EBC, "dclk_ebc", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(23), 0, 2, MFLAGS, 8, 8, DFLAGS, + RK2928_CLKGATE_CON(3), 4, GFLAGS), + + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + + COMPOSITE_NODIV(SCLK_CIF_SRC, "sclk_cif_src", mux_pll_src_4plls_p, 0, + RK2928_CLKSEL_CON(29), 0, 2, MFLAGS, + RK2928_CLKGATE_CON(3), 7, GFLAGS), + MUX(SCLK_CIF_OUT_SRC, "sclk_cif_out_src", mux_clk_cif_out_src_p, 0, + RK2928_CLKSEL_CON(13), 14, 2, MFLAGS), + DIV(SCLK_CIF_OUT, "sclk_cif_out", "sclk_cif_out_src", 0, + RK2928_CLKSEL_CON(29), 2, 5, DFLAGS), + + COMPOSITE(0, "i2s0_src", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(9), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK2928_CLKGATE_CON(4), 4, GFLAGS), + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(8), 0, + RK2928_CLKGATE_CON(4), 5, GFLAGS, + &rk3128_i2s0_fracmux), + GATE(SCLK_I2S0, "sclk_i2s0", "i2s0_pre", CLK_SET_RATE_PARENT, + RK2928_CLKGATE_CON(4), 6, GFLAGS), + + COMPOSITE(0, "i2s1_src", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(7), 0, + RK2928_CLKGATE_CON(0), 10, GFLAGS, + &rk3128_i2s1_fracmux), + GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT, + RK2928_CLKGATE_CON(0), 14, GFLAGS), + COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_out", mux_i2s_out_p, 0, + RK2928_CLKSEL_CON(3), 12, 1, MFLAGS, + RK2928_CLKGATE_CON(0), 13, GFLAGS), + + COMPOSITE(0, "sclk_spdif_src", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(6), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK2928_CLKGATE_CON(2), 10, GFLAGS), + COMPOSITE_FRACMUX(0, "spdif_frac", "sclk_spdif_src", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(20), 0, + RK2928_CLKGATE_CON(2), 12, GFLAGS, + &rk3128_spdif_fracmux), + + GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(1), 3, GFLAGS), + + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin12m", 0, + RK2928_CLKGATE_CON(1), 5, GFLAGS), + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin12m", 0, + RK2928_CLKGATE_CON(1), 6, GFLAGS), + + COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0, + RK2928_CLKSEL_CON(24), 8, 8, DFLAGS, + RK2928_CLKGATE_CON(2), 8, GFLAGS), + + COMPOSITE(ACLK_GPU, "aclk_gpu", mux_pll_src_5plls_p, 0, + RK2928_CLKSEL_CON(34), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(3), 13, GFLAGS), + + COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK2928_CLKGATE_CON(2), 9, GFLAGS), + + /* PD_UART */ + COMPOSITE(0, "uart0_src", mux_pll_src_4plls_p, 0, + RK2928_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 8, GFLAGS), + MUX(0, "uart12_src", mux_pll_src_4plls_p, 0, + RK2928_CLKSEL_CON(13), 14, 2, MFLAGS), + COMPOSITE_NOMUX(0, "uart1_src", "uart12_src", 0, + RK2928_CLKSEL_CON(14), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 10, GFLAGS), + COMPOSITE_NOMUX(0, "uart2_src", "uart12_src", 0, + RK2928_CLKSEL_CON(15), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(17), 0, + RK2928_CLKGATE_CON(1), 9, GFLAGS, + &rk3128_uart0_fracmux), + COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(18), 0, + RK2928_CLKGATE_CON(1), 11, GFLAGS, + &rk3128_uart1_fracmux), + COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(19), 0, + RK2928_CLKGATE_CON(1), 13, GFLAGS, + &rk3128_uart2_fracmux), + + COMPOSITE(SCLK_MAC_SRC, "sclk_gmac_src", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(1), 7, GFLAGS), + MUX(SCLK_MAC, "sclk_gmac", mux_sclk_gmac_p, 0, + RK2928_CLKSEL_CON(5), 15, 1, MFLAGS), + GATE(SCLK_MAC_REFOUT, "sclk_mac_refout", "sclk_gmac", 0, + RK2928_CLKGATE_CON(2), 5, GFLAGS), + GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_gmac", 0, + RK2928_CLKGATE_CON(2), 4, GFLAGS), + GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_gmac", 0, + RK2928_CLKGATE_CON(2), 6, GFLAGS), + GATE(SCLK_MAC_TX, "sclk_mac_tx", "sclk_gmac", 0, + RK2928_CLKGATE_CON(2), 7, GFLAGS), + + COMPOSITE(SCLK_TSP, "sclk_tsp", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(1), 14, GFLAGS), + + COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(10), 15, GFLAGS), + + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0, + RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK2928_CLKGATE_CON(3), 15, GFLAGS), + + COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0, + RK2928_CLKSEL_CON(29), 8, 6, DFLAGS, + RK2928_CLKGATE_CON(1), 0, GFLAGS), + + /* + * Clock-Architecture Diagram 3 + */ + + /* PD_VOP */ + GATE(ACLK_LCDC0, "aclk_lcdc0", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), + GATE(ACLK_CIF, "aclk_cif", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 5, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 11, GFLAGS), + GATE(0, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS), + + GATE(ACLK_IEP, "aclk_iep", "aclk_vio1", 0, RK2928_CLKGATE_CON(9), 8, GFLAGS), + GATE(0, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 10, GFLAGS), + + GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), + GATE(PCLK_MIPI, "pclk_mipi", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), + GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_vio", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), + GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 7, GFLAGS), + GATE(0, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), + GATE(HCLK_CIF, "hclk_cif", "hclk_vio", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), + GATE(HCLK_EBC, "hclk_ebc", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 9, GFLAGS), + + /* PD_PERI */ + GATE(0, "aclk_peri_axi", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS), + GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK2928_CLKGATE_CON(10), 10, GFLAGS), + GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS), + GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), + GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), + + GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), + GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), + GATE(HCLK_I2S_2CH, "hclk_i2s_2ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS), + GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), + GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 13, GFLAGS), + GATE(0, "hclk_peri_ahb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS), + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), + GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 12, GFLAGS), + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), + GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS), + GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), + GATE(0, "hclk_emmc_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 6, GFLAGS), + GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), + GATE(HCLK_USBHOST, "hclk_usbhost", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 14, GFLAGS), + + GATE(PCLK_SIM_CARD, "pclk_sim_card", "pclk_peri", 0, RK2928_CLKGATE_CON(9), 12, GFLAGS), + GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS), + GATE(0, "pclk_peri_axi", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS), + GATE(PCLK_PWM, "pclk_pwm", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS), + GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS), + GATE(PCLK_EFUSE, "pclk_efuse", "pclk_peri", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 7, GFLAGS), + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), + + /* PD_BUS */ + GATE(0, "aclk_initmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS), + + GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS), + GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), + + GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), + GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), + GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS), + GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), + GATE(0, "pclk_mipiphy", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 0, GFLAGS), + + GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 2, GFLAGS), + GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 3, GFLAGS), + + /* PD_MMC */ + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0), + + MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0), + + MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), +}; + +static const char *const rk3128_critical_clocks[] __initconst = { + "aclk_cpu", + "hclk_cpu", + "pclk_cpu", + "aclk_peri", + "hclk_peri", + "pclk_peri", +}; + +static void __init rk3128_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } + + rockchip_clk_register_plls(ctx, rk3128_pll_clks, + ARRAY_SIZE(rk3128_pll_clks), + RK3128_GRF_SOC_STATUS0); + rockchip_clk_register_branches(ctx, rk3128_clk_branches, + ARRAY_SIZE(rk3128_clk_branches)); + rockchip_clk_protect_critical(rk3128_critical_clocks, + ARRAY_SIZE(rk3128_critical_clocks)); + + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), + &rk3128_cpuclk_data, rk3128_cpuclk_rates, + ARRAY_SIZE(rk3128_cpuclk_rates)); + + rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); + + rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); +} + +CLK_OF_DECLARE(rk3128_cru, "rockchip,rk3128-cru", rk3128_clk_init); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index db6e5a9e6de6..bb405d9044a3 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -86,25 +86,43 @@ static struct rockchip_pll_rate_table rk3228_pll_rates[] = { #define RK3228_DIV_PCLK_MASK 0x7 #define RK3228_DIV_PCLK_SHIFT 12 -#define RK3228_CLKSEL1(_core_peri_div) \ +#define RK3228_CLKSEL1(_core_aclk_div, _core_peri_div) \ { \ .reg = RK2928_CLKSEL_CON(1), \ .val = HIWORD_UPDATE(_core_peri_div, RK3228_DIV_PERI_MASK, \ - RK3228_DIV_PERI_SHIFT) \ - } + RK3228_DIV_PERI_SHIFT) | \ + HIWORD_UPDATE(_core_aclk_div, RK3228_DIV_ACLK_MASK, \ + RK3228_DIV_ACLK_SHIFT), \ +} -#define RK3228_CPUCLK_RATE(_prate, _core_peri_div) \ - { \ - .prate = _prate, \ - .divs = { \ - RK3228_CLKSEL1(_core_peri_div), \ - }, \ +#define RK3228_CPUCLK_RATE(_prate, _core_aclk_div, _core_peri_div) \ + { \ + .prate = _prate, \ + .divs = { \ + RK3228_CLKSEL1(_core_aclk_div, _core_peri_div), \ + }, \ } static struct rockchip_cpuclk_rate_table rk3228_cpuclk_rates[] __initdata = { - RK3228_CPUCLK_RATE(816000000, 4), - RK3228_CPUCLK_RATE(600000000, 4), - RK3228_CPUCLK_RATE(312000000, 4), + RK3228_CPUCLK_RATE(1800000000, 1, 7), + RK3228_CPUCLK_RATE(1704000000, 1, 7), + RK3228_CPUCLK_RATE(1608000000, 1, 7), + RK3228_CPUCLK_RATE(1512000000, 1, 7), + RK3228_CPUCLK_RATE(1488000000, 1, 5), + RK3228_CPUCLK_RATE(1416000000, 1, 5), + RK3228_CPUCLK_RATE(1392000000, 1, 5), + RK3228_CPUCLK_RATE(1296000000, 1, 5), + RK3228_CPUCLK_RATE(1200000000, 1, 5), + RK3228_CPUCLK_RATE(1104000000, 1, 5), + RK3228_CPUCLK_RATE(1008000000, 1, 5), + RK3228_CPUCLK_RATE(912000000, 1, 5), + RK3228_CPUCLK_RATE(816000000, 1, 3), + RK3228_CPUCLK_RATE(696000000, 1, 3), + RK3228_CPUCLK_RATE(600000000, 1, 3), + RK3228_CPUCLK_RATE(408000000, 1, 1), + RK3228_CPUCLK_RATE(312000000, 1, 1), + RK3228_CPUCLK_RATE(216000000, 1, 1), + RK3228_CPUCLK_RATE(96000000, 1, 1), }; static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { @@ -252,15 +270,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 1, GFLAGS), COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS), - GATE(ARMCLK, "aclk_cpu", "aclk_cpu_src", 0, + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), - COMPOSITE_NOMUX(0, "hclk_cpu", "aclk_cpu_src", 0, + COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0, RK2928_CLKSEL_CON(1), 8, 2, DFLAGS, RK2928_CLKGATE_CON(6), 1, GFLAGS), COMPOSITE_NOMUX(0, "pclk_bus_src", "aclk_cpu_src", 0, RK2928_CLKSEL_CON(1), 12, 3, DFLAGS, RK2928_CLKGATE_CON(6), 2, GFLAGS), - GATE(0, "pclk_cpu", "pclk_bus_src", 0, + GATE(PCLK_CPU, "pclk_cpu", "pclk_bus_src", 0, RK2928_CLKGATE_CON(6), 3, GFLAGS), GATE(0, "pclk_phy_pre", "pclk_bus_src", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), @@ -268,58 +286,58 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(6), 13, GFLAGS), /* PD_VIDEO */ - COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), - FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, + FACTOR_GATE(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 4, GFLAGS), - COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 2, GFLAGS), - FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, + FACTOR_GATE(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 5, GFLAGS), - COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, + COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 3, GFLAGS), - COMPOSITE(0, "sclk_vdec_core", mux_pll_src_4plls_p, 0, + COMPOSITE(SCLK_VDEC_CORE, "sclk_vdec_core", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(34), 13, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 4, GFLAGS), /* PD_VIO */ - COMPOSITE(0, "aclk_iep_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_IEP_PRE, "aclk_iep_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(31), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 0, GFLAGS), - DIV(0, "hclk_vio_pre", "aclk_iep_pre", 0, + DIV(HCLK_VIO_PRE, "hclk_vio_pre", "aclk_iep_pre", 0, RK2928_CLKSEL_CON(2), 0, 5, DFLAGS), - COMPOSITE(0, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_HDCP_PRE, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(31), 13, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(1), 4, GFLAGS), MUX(0, "sclk_rga_src", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(33), 13, 2, MFLAGS), - COMPOSITE_NOMUX(0, "aclk_rga_pre", "sclk_rga_src", 0, + COMPOSITE_NOMUX(ACLK_RGA_PRE, "aclk_rga_pre", "sclk_rga_src", 0, RK2928_CLKSEL_CON(33), 8, 5, DFLAGS, RK2928_CLKGATE_CON(1), 2, GFLAGS), - COMPOSITE(0, "sclk_rga", mux_sclk_rga_p, 0, + COMPOSITE(SCLK_RGA, "sclk_rga", mux_sclk_rga_p, 0, RK2928_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 6, GFLAGS), - COMPOSITE(0, "aclk_vop_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(33), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(1), 1, GFLAGS), - COMPOSITE(0, "sclk_hdcp", mux_pll_src_3plls_p, 0, + COMPOSITE(SCLK_HDCP, "sclk_hdcp", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 6, DFLAGS, RK2928_CLKGATE_CON(3), 5, GFLAGS), GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK2928_CLKGATE_CON(3), 7, GFLAGS), - COMPOSITE(0, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0, + COMPOSITE(SCLK_HDMI_CEC, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0, RK2928_CLKSEL_CON(21), 14, 2, MFLAGS, 0, 14, DFLAGS, RK2928_CLKGATE_CON(3), 8, GFLAGS), @@ -354,18 +372,18 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), - COMPOSITE(0, "sclk_crypto", mux_pll_src_2plls_p, 0, + COMPOSITE(SCLK_CRYPTO, "sclk_crypto", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(24), 5, 1, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(2), 7, GFLAGS), - COMPOSITE(0, "sclk_tsp", mux_pll_src_2plls_p, 0, + COMPOSITE(SCLK_TSP, "sclk_tsp", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(22), 15, 1, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), - GATE(0, "sclk_hsadc", "ext_hsadc", 0, + GATE(SCLK_HSADC, "sclk_hsadc", "ext_hsadc", 0, RK2928_CLKGATE_CON(10), 12, GFLAGS), - COMPOSITE(0, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS, RK2928_CLKGATE_CON(2), 15, GFLAGS), @@ -445,12 +463,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(2), 12, GFLAGS, &rk3228_spdif_fracmux), - GATE(0, "jtag", "ext_jtag", 0, + GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 3, GFLAGS), - GATE(0, "sclk_otgphy0", "xin24m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", 0, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(0, "sclk_otgphy1", "xin24m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", 0, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, @@ -526,28 +544,28 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { */ /* PD_VOP */ - GATE(0, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS), GATE(0, "aclk_rga_noc", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 11, GFLAGS), - GATE(0, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), + GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS), GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS), - GATE(0, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), + GATE(ACLK_HDCP, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), GATE(0, "aclk_hdcp_noc", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(13), 10, GFLAGS), - GATE(0, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), - GATE(0, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), + GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS), GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS), GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), - GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), - GATE(0, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), + GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), + GATE(HCLK_HDCP_MMU, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), - GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), - GATE(0, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), + GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), + GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), /* PD_PERI */ GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 0, GFLAGS), @@ -557,12 +575,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 1, GFLAGS), GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 2, GFLAGS), GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 3, GFLAGS), - GATE(0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS), + GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS), GATE(0, "hclk_host0_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 7, GFLAGS), - GATE(0, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS), + GATE(HCLK_HOST1, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS), GATE(0, "hclk_host1_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 9, GFLAGS), - GATE(0, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS), - GATE(0, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS), + GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS), + GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS), GATE(0, "hclk_otg_pmu", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 13, GFLAGS), GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS), GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS), @@ -571,7 +589,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS), /* PD_GPU */ - GATE(0, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS), + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS), GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS), /* PD_BUS */ @@ -585,16 +603,16 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS), GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS), GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS), - GATE(0, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS), - GATE(0, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), - GATE(0, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), + GATE(HCLK_TSP, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS), + GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), + GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS), GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS), - GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), - GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS), + GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), + GATE(PCLK_EFUSE_256, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS), GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 15, GFLAGS), GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 0, GFLAGS), GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), @@ -622,13 +640,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), - GATE(0, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS), + GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS), GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 4, GFLAGS), - GATE(0, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS), + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS), GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 6, GFLAGS), - GATE(0, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS), + GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS), GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 5, GFLAGS), - GATE(0, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS), + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS), GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 7, GFLAGS), /* PD_MMC */ @@ -644,9 +662,37 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { static const char *const rk3228_critical_clocks[] __initconst = { "aclk_cpu", + "pclk_cpu", + "hclk_cpu", "aclk_peri", "hclk_peri", "pclk_peri", + "aclk_rga_noc", + "aclk_iep_noc", + "aclk_vop_noc", + "aclk_hdcp_noc", + "hclk_vio_ahb_arbi", + "hclk_vio_noc", + "hclk_vop_noc", + "hclk_host0_arb", + "hclk_host1_arb", + "hclk_host2_arb", + "hclk_otg_pmu", + "aclk_gpu_noc", + "sclk_initmem_mbist", + "aclk_initmem", + "hclk_rom", + "pclk_ddrupctl", + "pclk_ddrmon", + "pclk_msch_noc", + "pclk_stimer", + "pclk_ddrphy", + "pclk_acodecphy", + "pclk_phy_noc", + "aclk_vpu_noc", + "aclk_rkvdec_noc", + "hclk_vpu_noc", + "hclk_rkvdec_noc", }; static void __init rk3228_clk_init(struct device_node *np) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 68ba7d4105e7..450de24a1b42 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -292,13 +292,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 6, GFLAGS), - COMPOSITE_NOMUX(0, "atclk", "armclk", 0, + COMPOSITE_NOMUX(0, "atclk", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 7, GFLAGS), COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 8, GFLAGS), - GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, + GATE(0, "pclk_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(12), 9, GFLAGS), GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(12), 10, GFLAGS), @@ -626,7 +626,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out", RK3288_CLKSEL_CON(22), 7, IFLAGS), - GATE(0, "jtag", "ext_jtag", 0, + GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 14, GFLAGS), COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0, @@ -635,7 +635,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, RK3288_CLKGATE_CON(3), 6, GFLAGS), - GATE(0, "hsicphy12m_xin12m", "xin12m", 0, + GATE(0, "hsicphy12m_xin12m", "xin12m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 9, GFLAGS), DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0, RK3288_CLKSEL_CON(11), 8, 6, DFLAGS), @@ -816,6 +816,12 @@ static const char *const rk3288_critical_clocks[] __initconst = { "pclk_alive_niu", "pclk_pd_pmu", "pclk_pmu_niu", + "pclk_core_niu", + "pclk_ddrupctl0", + "pclk_publ0", + "pclk_ddrupctl1", + "pclk_publ1", + "pmu_hclk_otg0", }; static void __iomem *rk3288_cru_base; diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 024762d3214d..fc56565379dd 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -638,7 +638,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { GATE(SCLK_MAC_TX, "sclk_mac_tx", "mac_clk", 0, RK3368_CLKGATE_CON(7), 5, GFLAGS), - GATE(0, "jtag", "ext_jtag", 0, + GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(7), 0, GFLAGS), COMPOSITE_NODIV(0, "hsic_usbphy_480m", mux_hsic_usbphy480m_p, 0, @@ -861,6 +861,9 @@ static const char *const rk3368_critical_clocks[] __initconst = { "pclk_pd_alive", "pclk_peri", "hclk_peri", + "pclk_ddrphy", + "pclk_ddrupctl", + "pmu_hclk_otg0", }; static void __init rk3368_clk_init(struct device_node *np) diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index fa3cbef08776..6847120b61cd 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -1066,13 +1066,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* cif_testout */ MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, RK3399_CLKSEL_CON(38), 6, 2, MFLAGS), - COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0, + COMPOSITE(SCLK_TESTCLKOUT1, "clk_testout1", mux_clk_testout1_p, 0, RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS, RK3399_CLKGATE_CON(13), 14, GFLAGS), MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, RK3399_CLKSEL_CON(38), 14, 2, MFLAGS), - COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0, + COMPOSITE(SCLK_TESTCLKOUT2, "clk_testout2", mux_clk_testout2_p, 0, RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS, RK3399_CLKGATE_CON(13), 15, GFLAGS), diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 8bf7e805fd34..6686e8ba61f9 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -410,7 +410,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, { struct exynos_cpuclk *cpuclk; struct clk_init_data init; - struct clk *clk; + struct clk *parent_clk; int ret = 0; cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); @@ -440,15 +440,15 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, goto free_cpuclk; } - clk = __clk_lookup(parent); - if (!clk) { + parent_clk = __clk_lookup(parent); + if (!parent_clk) { pr_err("%s: could not lookup parent clock %s\n", __func__, parent); ret = -EINVAL; goto free_cpuclk; } - ret = clk_notifier_register(clk, &cpuclk->clk_nb); + ret = clk_notifier_register(parent_clk, &cpuclk->clk_nb); if (ret) { pr_err("%s: failed to register clock notifier for %s\n", __func__, name); @@ -463,20 +463,19 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, goto unregister_clk_nb; } - clk = clk_register(NULL, &cpuclk->hw); - if (IS_ERR(clk)) { + ret = clk_hw_register(NULL, &cpuclk->hw); + if (ret) { pr_err("%s: could not register cpuclk %s\n", __func__, name); - ret = PTR_ERR(clk); goto free_cpuclk_data; } - samsung_clk_add_lookup(ctx, clk, lookup_id); + samsung_clk_add_lookup(ctx, &cpuclk->hw, lookup_id); return 0; free_cpuclk_data: kfree(cpuclk->cfg); unregister_clk_nb: - clk_notifier_unregister(__clk_lookup(parent), &cpuclk->clk_nb); + clk_notifier_unregister(parent_clk, &cpuclk->clk_nb); free_cpuclk: kfree(cpuclk); return ret; diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index cb7df358a27d..85edeb738853 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -22,9 +22,8 @@ #include <dt-bindings/clock/exynos-audss-clk.h> static DEFINE_SPINLOCK(lock); -static struct clk **clk_table; static void __iomem *reg_base; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_data; /* * On Exynos5420 this will be a clock which has to be enabled before any * access to audss registers. Typically a child of EPLL. @@ -110,18 +109,18 @@ static void exynos_audss_clk_teardown(void) int i; for (i = EXYNOS_MOUT_AUDSS; i < EXYNOS_DOUT_SRP; i++) { - if (!IS_ERR(clk_table[i])) - clk_unregister_mux(clk_table[i]); + if (!IS_ERR(clk_data->hws[i])) + clk_hw_unregister_mux(clk_data->hws[i]); } for (; i < EXYNOS_SRP_CLK; i++) { - if (!IS_ERR(clk_table[i])) - clk_unregister_divider(clk_table[i]); + if (!IS_ERR(clk_data->hws[i])) + clk_hw_unregister_divider(clk_data->hws[i]); } - for (; i < clk_data.clk_num; i++) { - if (!IS_ERR(clk_table[i])) - clk_unregister_gate(clk_table[i]); + for (; i < clk_data->num; i++) { + if (!IS_ERR(clk_data->hws[i])) + clk_hw_unregister_gate(clk_data->hws[i]); } } @@ -133,6 +132,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) const char *sclk_pcm_p = "sclk_pcm0"; struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; const struct exynos_audss_clk_drvdata *variant; + struct clk_hw **clk_table; struct resource *res; int i, ret = 0; @@ -149,14 +149,15 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) epll = ERR_PTR(-ENODEV); - clk_table = devm_kzalloc(&pdev->dev, - sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, + clk_data = devm_kzalloc(&pdev->dev, + sizeof(*clk_data) + + sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS, GFP_KERNEL); - if (!clk_table) + if (!clk_data) return -ENOMEM; - clk_data.clks = clk_table; - clk_data.clk_num = variant->num_clks; + clk_data->num = variant->num_clks; + clk_table = clk_data->hws; pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); pll_in = devm_clk_get(&pdev->dev, "pll_in"); @@ -176,7 +177,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) } } } - clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", + clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", mout_audss_p, ARRAY_SIZE(mout_audss_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); @@ -187,53 +188,53 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) mout_i2s_p[1] = __clk_get_name(cdclk); if (!IS_ERR(sclk_audio)) mout_i2s_p[2] = __clk_get_name(sclk_audio); - clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s", + clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(NULL, "mout_i2s", mout_i2s_p, ARRAY_SIZE(mout_i2s_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); - clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp", + clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp", "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); - clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL, + clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, "dout_aud_bus", "dout_srp", 0, reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); - clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s", + clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s", "mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0, &lock); - clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk", + clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(NULL, "srp_clk", "dout_srp", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 0, 0, &lock); - clk_table[EXYNOS_I2S_BUS] = clk_register_gate(NULL, "i2s_bus", + clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(NULL, "i2s_bus", "dout_aud_bus", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 2, 0, &lock); - clk_table[EXYNOS_SCLK_I2S] = clk_register_gate(NULL, "sclk_i2s", + clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(NULL, "sclk_i2s", "dout_i2s", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 3, 0, &lock); - clk_table[EXYNOS_PCM_BUS] = clk_register_gate(NULL, "pcm_bus", + clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(NULL, "pcm_bus", "sclk_pcm", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 4, 0, &lock); sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in"); if (!IS_ERR(sclk_pcm_in)) sclk_pcm_p = __clk_get_name(sclk_pcm_in); - clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm", + clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(NULL, "sclk_pcm", sclk_pcm_p, CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 5, 0, &lock); if (variant->has_adma_clk) { - clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma", + clk_table[EXYNOS_ADMA] = clk_hw_register_gate(NULL, "adma", "dout_srp", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 9, 0, &lock); } - for (i = 0; i < clk_data.clk_num; i++) { + for (i = 0; i < clk_data->num; i++) { if (IS_ERR(clk_table[i])) { dev_err(&pdev->dev, "failed to register clock %d\n", i); ret = PTR_ERR(clk_table[i]); @@ -241,8 +242,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) } } - ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, - &clk_data); + ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, + clk_data); if (ret) { dev_err(&pdev->dev, "failed to add clock provider\n"); goto unregister; diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c index 6c6afb87b4ce..a21aea062bae 100644 --- a/drivers/clk/samsung/clk-exynos-clkout.c +++ b/drivers/clk/samsung/clk-exynos-clkout.c @@ -29,10 +29,9 @@ struct exynos_clkout { struct clk_gate gate; struct clk_mux mux; spinlock_t slock; - struct clk_onecell_data data; - struct clk *clk_table[EXYNOS_CLKOUT_NR_CLKS]; void __iomem *reg; u32 pmu_debug_save; + struct clk_hw_onecell_data data; }; static struct exynos_clkout *clkout; @@ -62,7 +61,9 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) int ret; int i; - clkout = kzalloc(sizeof(*clkout), GFP_KERNEL); + clkout = kzalloc(sizeof(*clkout) + + sizeof(*clkout->data.hws) * EXYNOS_CLKOUT_NR_CLKS, + GFP_KERNEL); if (!clkout) return; @@ -100,17 +101,16 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; clkout->mux.lock = &clkout->slock; - clkout->clk_table[0] = clk_register_composite(NULL, "clkout", + clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout", parent_names, parent_count, &clkout->mux.hw, &clk_mux_ops, NULL, NULL, &clkout->gate.hw, &clk_gate_ops, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT); - if (IS_ERR(clkout->clk_table[0])) + if (IS_ERR(clkout->data.hws[0])) goto err_unmap; - clkout->data.clks = clkout->clk_table; - clkout->data.clk_num = EXYNOS_CLKOUT_NR_CLKS; - ret = of_clk_add_provider(node, of_clk_src_onecell_get, &clkout->data); + clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, &clkout->data); if (ret) goto err_clk_unreg; @@ -119,7 +119,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) return; err_clk_unreg: - clk_unregister(clkout->clk_table[0]); + clk_hw_unregister(clkout->data.hws[0]); err_unmap: iounmap(clkout->reg); clks_put: diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index cdc092a1d9ef..0748a0b333c5 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -487,6 +487,7 @@ PNAME(mout_group12_5800_p) = { "dout_aclkfl1_550_cam", "dout_sclk_sw" }; PNAME(mout_group13_5800_p) = { "dout_osc_div", "mout_sw_aclkfl1_550_cam" }; PNAME(mout_group14_5800_p) = { "dout_aclk550_cam", "dout_sclk_sw" }; PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; +PNAME(mout_group16_5800_p) = { "dout_osc_div", "mout_mau_epll_clk" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock @@ -536,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), - MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, SRC_TOP7, - 20, 2), + MUX(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, + SRC_TOP7, 20, 2), MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), @@ -546,6 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), + MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p, + SRC_TOP9, 8, 1), MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, SRC_TOP9, 16, 1), MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, @@ -703,7 +706,7 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), - MUX(0, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), + MUX(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), @@ -1277,6 +1280,21 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini PLL_35XX_RATE(200000000, 200, 3, 3), }; +static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { + PLL_36XX_RATE(600000000U, 100, 2, 1, 0), + PLL_36XX_RATE(400000000U, 200, 3, 2, 0), + PLL_36XX_RATE(393216000U, 197, 3, 2, 25690), + PLL_36XX_RATE(361267200U, 301, 5, 2, 3671), + PLL_36XX_RATE(200000000U, 200, 3, 3, 0), + PLL_36XX_RATE(196608000U, 197, 3, 3, -25690), + PLL_36XX_RATE(180633600U, 301, 5, 3, 3671), + PLL_36XX_RATE(131072000U, 131, 3, 3, 4719), + PLL_36XX_RATE(100000000U, 200, 3, 4, 0), + PLL_36XX_RATE(65536000U, 131, 3, 4, 4719), + PLL_36XX_RATE(49152000U, 197, 3, 5, 25690), + PLL_36XX_RATE(32768000U, 131, 3, 5, 4719), +}; + static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, APLL_CON0, NULL), @@ -1284,7 +1302,7 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { CPLL_CON0, NULL), [dpll] = PLL(pll_2550, CLK_FOUT_DPLL, "fout_dpll", "fin_pll", DPLL_LOCK, DPLL_CON0, NULL), - [epll] = PLL(pll_2650, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK, + [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK, EPLL_CON0, NULL), [rpll] = PLL(pll_2650, CLK_FOUT_RPLL, "fout_rpll", "fin_pll", RPLL_LOCK, RPLL_CON0, NULL), @@ -1399,6 +1417,7 @@ static void __init exynos5x_clk_init(struct device_node *np, if (_get_rate("fin_pll") == 24 * MHZ) { exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; + exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl; } diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 52290894857a..037c61484098 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -23,6 +23,10 @@ struct samsung_clk_pll { struct clk_hw hw; void __iomem *lock_reg; void __iomem *con_reg; + /* PLL enable control bit offset in @con_reg register */ + unsigned short enable_offs; + /* PLL lock status bit offset in @con_reg register */ + unsigned short lock_offs; enum samsung_pll_type type; unsigned int rate_count; const struct samsung_pll_rate_table *rate_table; @@ -61,6 +65,34 @@ static long samsung_pll_round_rate(struct clk_hw *hw, return rate_table[i - 1].rate; } +static int samsung_pll3xxx_enable(struct clk_hw *hw) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 tmp; + + tmp = readl_relaxed(pll->con_reg); + tmp |= BIT(pll->enable_offs); + writel_relaxed(tmp, pll->con_reg); + + /* wait lock time */ + do { + cpu_relax(); + tmp = readl_relaxed(pll->con_reg); + } while (!(tmp & BIT(pll->lock_offs))); + + return 0; +} + +static void samsung_pll3xxx_disable(struct clk_hw *hw) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 tmp; + + tmp = readl_relaxed(pll->con_reg); + tmp &= ~BIT(pll->enable_offs); + writel_relaxed(tmp, pll->con_reg); +} + /* * PLL2126 Clock Type */ @@ -142,34 +174,6 @@ static const struct clk_ops samsung_pll3000_clk_ops = { #define PLL35XX_LOCK_STAT_SHIFT (29) #define PLL35XX_ENABLE_SHIFT (31) -static int samsung_pll35xx_enable(struct clk_hw *hw) -{ - struct samsung_clk_pll *pll = to_clk_pll(hw); - u32 tmp; - - tmp = readl_relaxed(pll->con_reg); - tmp |= BIT(PLL35XX_ENABLE_SHIFT); - writel_relaxed(tmp, pll->con_reg); - - /* wait_lock_time */ - do { - cpu_relax(); - tmp = readl_relaxed(pll->con_reg); - } while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT))); - - return 0; -} - -static void samsung_pll35xx_disable(struct clk_hw *hw) -{ - struct samsung_clk_pll *pll = to_clk_pll(hw); - u32 tmp; - - tmp = readl_relaxed(pll->con_reg); - tmp &= ~BIT(PLL35XX_ENABLE_SHIFT); - writel_relaxed(tmp, pll->con_reg); -} - static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -238,12 +242,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, (rate->sdiv << PLL35XX_SDIV_SHIFT); writel_relaxed(tmp, pll->con_reg); - /* wait_lock_time if enabled */ - if (tmp & BIT(PLL35XX_ENABLE_SHIFT)) { + /* Wait until the PLL is locked if it is enabled. */ + if (tmp & BIT(pll->enable_offs)) { do { cpu_relax(); tmp = readl_relaxed(pll->con_reg); - } while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT))); + } while (!(tmp & BIT(pll->lock_offs))); } return 0; } @@ -252,8 +256,8 @@ static const struct clk_ops samsung_pll35xx_clk_ops = { .recalc_rate = samsung_pll35xx_recalc_rate, .round_rate = samsung_pll_round_rate, .set_rate = samsung_pll35xx_set_rate, - .enable = samsung_pll35xx_enable, - .disable = samsung_pll35xx_disable, + .enable = samsung_pll3xxx_enable, + .disable = samsung_pll3xxx_disable, }; static const struct clk_ops samsung_pll35xx_clk_min_ops = { @@ -275,6 +279,7 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = { #define PLL36XX_SDIV_SHIFT (0) #define PLL36XX_KDIV_SHIFT (0) #define PLL36XX_LOCK_STAT_SHIFT (29) +#define PLL36XX_ENABLE_SHIFT (31) static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -354,10 +359,12 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, writel_relaxed(pll_con1, pll->con_reg + 4); /* wait_lock_time */ - do { - cpu_relax(); - tmp = readl_relaxed(pll->con_reg); - } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT))); + if (pll_con0 & BIT(pll->enable_offs)) { + do { + cpu_relax(); + tmp = readl_relaxed(pll->con_reg); + } while (!(tmp & BIT(pll->lock_offs))); + } return 0; } @@ -366,6 +373,8 @@ static const struct clk_ops samsung_pll36xx_clk_ops = { .recalc_rate = samsung_pll36xx_recalc_rate, .set_rate = samsung_pll36xx_set_rate, .round_rate = samsung_pll_round_rate, + .enable = samsung_pll3xxx_enable, + .disable = samsung_pll3xxx_disable, }; static const struct clk_ops samsung_pll36xx_clk_min_ops = { @@ -1244,7 +1253,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, void __iomem *base) { struct samsung_clk_pll *pll; - struct clk *clk; struct clk_init_data init; int ret, len; @@ -1288,6 +1296,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_1450x: case pll_1451x: case pll_1452x: + pll->enable_offs = PLL35XX_ENABLE_SHIFT; + pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT; if (!pll->rate_table) init.ops = &samsung_pll35xx_clk_min_ops; else @@ -1306,6 +1316,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, /* clk_ops for 36xx and 2650 are similar */ case pll_36xx: case pll_2650: + pll->enable_offs = PLL36XX_ENABLE_SHIFT; + pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT; if (!pll->rate_table) init.ops = &samsung_pll36xx_clk_min_ops; else @@ -1376,20 +1388,21 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, pll->lock_reg = base + pll_clk->lock_offset; pll->con_reg = base + pll_clk->con_offset; - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) { - pr_err("%s: failed to register pll clock %s : %ld\n", - __func__, pll_clk->name, PTR_ERR(clk)); + ret = clk_hw_register(NULL, &pll->hw); + if (ret) { + pr_err("%s: failed to register pll clock %s : %d\n", + __func__, pll_clk->name, ret); kfree(pll); return; } - samsung_clk_add_lookup(ctx, clk, pll_clk->id); + samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id); if (!pll_clk->alias) return; - ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name); + ret = clk_hw_register_clkdev(&pll->hw, pll_clk->alias, + pll_clk->dev_name); if (ret) pr_err("%s: failed to register lookup for %s : %d", __func__, pll_clk->name, ret); diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index a1ca0233cb4b..61eb8abbfd9c 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -103,8 +103,4 @@ struct samsung_pll_rate_table { unsigned int vsel; }; -extern struct clk * __init samsung_clk_register_pll2550x(const char *name, - const char *pname, const void __iomem *reg_base, - const unsigned long offset); - #endif /* __SAMSUNG_CLK_PLL_H */ diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c index ae9a595c72d0..077df3e539a7 100644 --- a/drivers/clk/samsung/clk-s3c2410-dclk.c +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c @@ -90,13 +90,13 @@ static const struct clk_ops s3c24xx_clkout_ops = { .determine_rate = __clk_mux_determine_rate, }; -static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, - const char **parent_names, u8 num_parents, +static struct clk_hw *s3c24xx_register_clkout(struct device *dev, + const char *name, const char **parent_names, u8 num_parents, u8 shift, u32 mask) { struct s3c24xx_clkout *clkout; - struct clk *clk; struct clk_init_data init; + int ret; /* allocate the clkout */ clkout = kzalloc(sizeof(*clkout), GFP_KERNEL); @@ -113,9 +113,11 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, clkout->mask = mask; clkout->hw.init = &init; - clk = clk_register(dev, &clkout->hw); + ret = clk_hw_register(dev, &clkout->hw); + if (ret) + return ERR_PTR(ret); - return clk; + return &clkout->hw; } /* @@ -125,11 +127,12 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, struct s3c24xx_dclk { struct device *dev; void __iomem *base; - struct clk_onecell_data clk_data; struct notifier_block dclk0_div_change_nb; struct notifier_block dclk1_div_change_nb; spinlock_t dclk_lock; unsigned long reg_save; + /* clk_data must be the last entry in the structure */ + struct clk_hw_onecell_data clk_data; }; #define to_s3c24xx_dclk0(x) \ @@ -240,28 +243,23 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) { struct s3c24xx_dclk *s3c24xx_dclk; struct resource *mem; - struct clk **clk_table; struct s3c24xx_dclk_drv_data *dclk_variant; + struct clk_hw **clk_table; int ret, i; - s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk), - GFP_KERNEL); + s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk) + + sizeof(*s3c24xx_dclk->clk_data.hws) * DCLK_MAX_CLKS, + GFP_KERNEL); if (!s3c24xx_dclk) return -ENOMEM; + clk_table = s3c24xx_dclk->clk_data.hws; + s3c24xx_dclk->dev = &pdev->dev; + s3c24xx_dclk->clk_data.num = DCLK_MAX_CLKS; platform_set_drvdata(pdev, s3c24xx_dclk); spin_lock_init(&s3c24xx_dclk->dclk_lock); - clk_table = devm_kzalloc(&pdev->dev, - sizeof(struct clk *) * DCLK_MAX_CLKS, - GFP_KERNEL); - if (!clk_table) - return -ENOMEM; - - s3c24xx_dclk->clk_data.clks = clk_table; - s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(s3c24xx_dclk->base)) @@ -271,29 +269,29 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) platform_get_device_id(pdev)->driver_data; - clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev, "mux_dclk0", + clk_table[MUX_DCLK0] = clk_hw_register_mux(&pdev->dev, "mux_dclk0", dclk_variant->mux_parent_names, dclk_variant->mux_num_parents, 0, s3c24xx_dclk->base, 1, 1, 0, &s3c24xx_dclk->dclk_lock); - clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev, "mux_dclk1", + clk_table[MUX_DCLK1] = clk_hw_register_mux(&pdev->dev, "mux_dclk1", dclk_variant->mux_parent_names, dclk_variant->mux_num_parents, 0, s3c24xx_dclk->base, 17, 1, 0, &s3c24xx_dclk->dclk_lock); - clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0", + clk_table[DIV_DCLK0] = clk_hw_register_divider(&pdev->dev, "div_dclk0", "mux_dclk0", 0, s3c24xx_dclk->base, 4, 4, 0, &s3c24xx_dclk->dclk_lock); - clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1", + clk_table[DIV_DCLK1] = clk_hw_register_divider(&pdev->dev, "div_dclk1", "mux_dclk1", 0, s3c24xx_dclk->base, 20, 4, 0, &s3c24xx_dclk->dclk_lock); - clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0", + clk_table[GATE_DCLK0] = clk_hw_register_gate(&pdev->dev, "gate_dclk0", "div_dclk0", CLK_SET_RATE_PARENT, s3c24xx_dclk->base, 0, 0, &s3c24xx_dclk->dclk_lock); - clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1", + clk_table[GATE_DCLK1] = clk_hw_register_gate(&pdev->dev, "gate_dclk1", "div_dclk1", CLK_SET_RATE_PARENT, s3c24xx_dclk->base, 16, 0, &s3c24xx_dclk->dclk_lock); @@ -312,15 +310,16 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) goto err_clk_register; } - ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL); + ret = clk_hw_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL); if (!ret) - ret = clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL); + ret = clk_hw_register_clkdev(clk_table[MUX_DCLK1], "dclk1", + NULL); if (!ret) - ret = clk_register_clkdev(clk_table[MUX_CLKOUT0], - "clkout0", NULL); + ret = clk_hw_register_clkdev(clk_table[MUX_CLKOUT0], + "clkout0", NULL); if (!ret) - ret = clk_register_clkdev(clk_table[MUX_CLKOUT1], - "clkout1", NULL); + ret = clk_hw_register_clkdev(clk_table[MUX_CLKOUT1], + "clkout1", NULL); if (ret) { dev_err(&pdev->dev, "failed to register aliases, %d\n", ret); goto err_clk_register; @@ -332,12 +331,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) s3c24xx_dclk->dclk1_div_change_nb.notifier_call = s3c24xx_dclk1_div_notify; - ret = clk_notifier_register(clk_table[DIV_DCLK0], + ret = clk_notifier_register(clk_table[DIV_DCLK0]->clk, &s3c24xx_dclk->dclk0_div_change_nb); if (ret) goto err_clk_register; - ret = clk_notifier_register(clk_table[DIV_DCLK1], + ret = clk_notifier_register(clk_table[DIV_DCLK1]->clk, &s3c24xx_dclk->dclk1_div_change_nb); if (ret) goto err_dclk_notify; @@ -345,12 +344,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) return 0; err_dclk_notify: - clk_notifier_unregister(clk_table[DIV_DCLK0], + clk_notifier_unregister(clk_table[DIV_DCLK0]->clk, &s3c24xx_dclk->dclk0_div_change_nb); err_clk_register: for (i = 0; i < DCLK_MAX_CLKS; i++) if (clk_table[i] && !IS_ERR(clk_table[i])) - clk_unregister(clk_table[i]); + clk_hw_unregister(clk_table[i]); return ret; } @@ -358,16 +357,16 @@ err_clk_register: static int s3c24xx_dclk_remove(struct platform_device *pdev) { struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev); - struct clk **clk_table = s3c24xx_dclk->clk_data.clks; + struct clk_hw **clk_table = s3c24xx_dclk->clk_data.hws; int i; - clk_notifier_unregister(clk_table[DIV_DCLK1], + clk_notifier_unregister(clk_table[DIV_DCLK1]->clk, &s3c24xx_dclk->dclk1_div_change_nb); - clk_notifier_unregister(clk_table[DIV_DCLK0], + clk_notifier_unregister(clk_table[DIV_DCLK0]->clk, &s3c24xx_dclk->dclk0_div_change_nb); for (i = 0; i < DCLK_MAX_CLKS; i++) - clk_unregister(clk_table[i]); + clk_hw_unregister(clk_table[i]); return 0; } diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c index c66ed2d1450e..b9641414ddc6 100644 --- a/drivers/clk/samsung/clk-s5pv210-audss.c +++ b/drivers/clk/samsung/clk-s5pv210-audss.c @@ -24,9 +24,8 @@ #include <dt-bindings/clock/s5pv210-audss.h> static DEFINE_SPINLOCK(lock); -static struct clk **clk_table; static void __iomem *reg_base; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_data; #define ASS_CLK_SRC 0x0 #define ASS_CLK_DIV 0x4 @@ -71,6 +70,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) const char *mout_audss_p[2]; const char *mout_i2s_p[3]; const char *hclk_p; + struct clk_hw **clk_table; struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -80,14 +80,16 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) return PTR_ERR(reg_base); } - clk_table = devm_kzalloc(&pdev->dev, - sizeof(struct clk *) * AUDSS_MAX_CLKS, + clk_data = devm_kzalloc(&pdev->dev, + sizeof(*clk_data) + + sizeof(*clk_data->hws) * AUDSS_MAX_CLKS, GFP_KERNEL); - if (!clk_table) + + if (!clk_data) return -ENOMEM; - clk_data.clks = clk_table; - clk_data.clk_num = AUDSS_MAX_CLKS; + clk_data->num = AUDSS_MAX_CLKS; + clk_table = clk_data->hws; hclk = devm_clk_get(&pdev->dev, "hclk"); if (IS_ERR(hclk)) { @@ -116,7 +118,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) else mout_audss_p[0] = "xxti"; mout_audss_p[1] = __clk_get_name(pll_in); - clk_table[CLK_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", + clk_table[CLK_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", mout_audss_p, ARRAY_SIZE(mout_audss_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); @@ -127,44 +129,44 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) else mout_i2s_p[1] = "iiscdclk0"; mout_i2s_p[2] = __clk_get_name(sclk_audio); - clk_table[CLK_MOUT_I2S_A] = clk_register_mux(NULL, "mout_i2s_audss", + clk_table[CLK_MOUT_I2S_A] = clk_hw_register_mux(NULL, "mout_i2s_audss", mout_i2s_p, ARRAY_SIZE(mout_i2s_p), CLK_SET_RATE_NO_REPARENT, reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); - clk_table[CLK_DOUT_AUD_BUS] = clk_register_divider(NULL, + clk_table[CLK_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, "dout_aud_bus", "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); - clk_table[CLK_DOUT_I2S_A] = clk_register_divider(NULL, "dout_i2s_audss", - "mout_i2s_audss", 0, reg_base + ASS_CLK_DIV, - 4, 4, 0, &lock); + clk_table[CLK_DOUT_I2S_A] = clk_hw_register_divider(NULL, + "dout_i2s_audss", "mout_i2s_audss", 0, + reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); - clk_table[CLK_I2S] = clk_register_gate(NULL, "i2s_audss", + clk_table[CLK_I2S] = clk_hw_register_gate(NULL, "i2s_audss", "dout_i2s_audss", CLK_SET_RATE_PARENT, reg_base + ASS_CLK_GATE, 6, 0, &lock); hclk_p = __clk_get_name(hclk); - clk_table[CLK_HCLK_I2S] = clk_register_gate(NULL, "hclk_i2s_audss", + clk_table[CLK_HCLK_I2S] = clk_hw_register_gate(NULL, "hclk_i2s_audss", hclk_p, CLK_IGNORE_UNUSED, reg_base + ASS_CLK_GATE, 5, 0, &lock); - clk_table[CLK_HCLK_UART] = clk_register_gate(NULL, "hclk_uart_audss", + clk_table[CLK_HCLK_UART] = clk_hw_register_gate(NULL, "hclk_uart_audss", hclk_p, CLK_IGNORE_UNUSED, reg_base + ASS_CLK_GATE, 4, 0, &lock); - clk_table[CLK_HCLK_HWA] = clk_register_gate(NULL, "hclk_hwa_audss", + clk_table[CLK_HCLK_HWA] = clk_hw_register_gate(NULL, "hclk_hwa_audss", hclk_p, CLK_IGNORE_UNUSED, reg_base + ASS_CLK_GATE, 3, 0, &lock); - clk_table[CLK_HCLK_DMA] = clk_register_gate(NULL, "hclk_dma_audss", + clk_table[CLK_HCLK_DMA] = clk_hw_register_gate(NULL, "hclk_dma_audss", hclk_p, CLK_IGNORE_UNUSED, reg_base + ASS_CLK_GATE, 2, 0, &lock); - clk_table[CLK_HCLK_BUF] = clk_register_gate(NULL, "hclk_buf_audss", + clk_table[CLK_HCLK_BUF] = clk_hw_register_gate(NULL, "hclk_buf_audss", hclk_p, CLK_IGNORE_UNUSED, reg_base + ASS_CLK_GATE, 1, 0, &lock); - clk_table[CLK_HCLK_RP] = clk_register_gate(NULL, "hclk_rp_audss", + clk_table[CLK_HCLK_RP] = clk_hw_register_gate(NULL, "hclk_rp_audss", hclk_p, CLK_IGNORE_UNUSED, reg_base + ASS_CLK_GATE, 0, 0, &lock); - for (i = 0; i < clk_data.clk_num; i++) { + for (i = 0; i < clk_data->num; i++) { if (IS_ERR(clk_table[i])) { dev_err(&pdev->dev, "failed to register clock %d\n", i); ret = PTR_ERR(clk_table[i]); @@ -172,8 +174,8 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) } } - ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, - &clk_data); + ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, + clk_data); if (ret) { dev_err(&pdev->dev, "failed to add clock provider\n"); goto unregister; @@ -186,9 +188,9 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) return 0; unregister: - for (i = 0; i < clk_data.clk_num; i++) { + for (i = 0; i < clk_data->num; i++) { if (!IS_ERR(clk_table[i])) - clk_unregister(clk_table[i]); + clk_hw_unregister(clk_table[i]); } return ret; diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index b7d87d6db9dc..7ce0fa86c5ff 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -60,23 +60,18 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks) { struct samsung_clk_provider *ctx; - struct clk **clk_table; int i; - ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL); + ctx = kzalloc(sizeof(struct samsung_clk_provider) + + sizeof(*ctx->clk_data.hws) * nr_clks, GFP_KERNEL); if (!ctx) panic("could not allocate clock provider context.\n"); - clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); - if (!clk_table) - panic("could not allocate clock lookup table\n"); - for (i = 0; i < nr_clks; ++i) - clk_table[i] = ERR_PTR(-ENOENT); + ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); ctx->reg_base = base; - ctx->clk_data.clks = clk_table; - ctx->clk_data.clk_num = nr_clks; + ctx->clk_data.num = nr_clks; spin_lock_init(&ctx->lock); return ctx; @@ -86,18 +81,18 @@ void __init samsung_clk_of_add_provider(struct device_node *np, struct samsung_clk_provider *ctx) { if (np) { - if (of_clk_add_provider(np, of_clk_src_onecell_get, + if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &ctx->clk_data)) panic("could not register clk provider\n"); } } /* add a clock instance to the clock lookup table used for dt based lookup */ -void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk, - unsigned int id) +void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, + struct clk_hw *clk_hw, unsigned int id) { - if (ctx->clk_data.clks && id) - ctx->clk_data.clks[id] = clk; + if (id) + ctx->clk_data.hws[id] = clk_hw; } /* register a list of aliases */ @@ -105,14 +100,9 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, const struct samsung_clock_alias *list, unsigned int nr_clk) { - struct clk *clk; + struct clk_hw *clk_hw; unsigned int idx, ret; - if (!ctx->clk_data.clks) { - pr_err("%s: clock table missing\n", __func__); - return; - } - for (idx = 0; idx < nr_clk; idx++, list++) { if (!list->id) { pr_err("%s: clock id missing for index %d\n", __func__, @@ -120,14 +110,15 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, continue; } - clk = ctx->clk_data.clks[list->id]; - if (!clk) { + clk_hw = ctx->clk_data.hws[list->id]; + if (!clk_hw) { pr_err("%s: failed to find clock %d\n", __func__, list->id); continue; } - ret = clk_register_clkdev(clk, list->alias, list->dev_name); + ret = clk_hw_register_clkdev(clk_hw, list->alias, + list->dev_name); if (ret) pr_err("%s: failed to register lookup %s\n", __func__, list->alias); @@ -139,25 +130,25 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, const struct samsung_fixed_rate_clock *list, unsigned int nr_clk) { - struct clk *clk; + struct clk_hw *clk_hw; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk = clk_register_fixed_rate(NULL, list->name, + clk_hw = clk_hw_register_fixed_rate(NULL, list->name, list->parent_name, list->flags, list->fixed_rate); - if (IS_ERR(clk)) { + if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(ctx, clk, list->id); + samsung_clk_add_lookup(ctx, clk_hw, list->id); /* * Unconditionally add a clock lookup for the fixed rate clocks. * There are not many of these on any of Samsung platforms. */ - ret = clk_register_clkdev(clk, list->name, NULL); + ret = clk_hw_register_clkdev(clk_hw, list->name, NULL); if (ret) pr_err("%s: failed to register clock lookup for %s", __func__, list->name); @@ -168,19 +159,19 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, const struct samsung_fixed_factor_clock *list, unsigned int nr_clk) { - struct clk *clk; + struct clk_hw *clk_hw; unsigned int idx; for (idx = 0; idx < nr_clk; idx++, list++) { - clk = clk_register_fixed_factor(NULL, list->name, + clk_hw = clk_hw_register_fixed_factor(NULL, list->name, list->parent_name, list->flags, list->mult, list->div); - if (IS_ERR(clk)) { + if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(ctx, clk, list->id); + samsung_clk_add_lookup(ctx, clk_hw, list->id); } } @@ -189,25 +180,25 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, const struct samsung_mux_clock *list, unsigned int nr_clk) { - struct clk *clk; + struct clk_hw *clk_hw; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk = clk_register_mux(NULL, list->name, list->parent_names, - list->num_parents, list->flags, + clk_hw = clk_hw_register_mux(NULL, list->name, + list->parent_names, list->num_parents, list->flags, ctx->reg_base + list->offset, list->shift, list->width, list->mux_flags, &ctx->lock); - if (IS_ERR(clk)) { + if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(ctx, clk, list->id); + samsung_clk_add_lookup(ctx, clk_hw, list->id); /* register a clock lookup only if a clock alias is specified */ if (list->alias) { - ret = clk_register_clkdev(clk, list->alias, + ret = clk_hw_register_clkdev(clk_hw, list->alias, list->dev_name); if (ret) pr_err("%s: failed to register lookup %s\n", @@ -221,32 +212,32 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, const struct samsung_div_clock *list, unsigned int nr_clk) { - struct clk *clk; + struct clk_hw *clk_hw; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { if (list->table) - clk = clk_register_divider_table(NULL, list->name, - list->parent_name, list->flags, + clk_hw = clk_hw_register_divider_table(NULL, + list->name, list->parent_name, list->flags, ctx->reg_base + list->offset, list->shift, list->width, list->div_flags, list->table, &ctx->lock); else - clk = clk_register_divider(NULL, list->name, + clk_hw = clk_hw_register_divider(NULL, list->name, list->parent_name, list->flags, ctx->reg_base + list->offset, list->shift, list->width, list->div_flags, &ctx->lock); - if (IS_ERR(clk)) { + if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(ctx, clk, list->id); + samsung_clk_add_lookup(ctx, clk_hw, list->id); /* register a clock lookup only if a clock alias is specified */ if (list->alias) { - ret = clk_register_clkdev(clk, list->alias, + ret = clk_hw_register_clkdev(clk_hw, list->alias, list->dev_name); if (ret) pr_err("%s: failed to register lookup %s\n", @@ -260,14 +251,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, const struct samsung_gate_clock *list, unsigned int nr_clk) { - struct clk *clk; + struct clk_hw *clk_hw; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk = clk_register_gate(NULL, list->name, list->parent_name, + clk_hw = clk_hw_register_gate(NULL, list->name, list->parent_name, list->flags, ctx->reg_base + list->offset, list->bit_idx, list->gate_flags, &ctx->lock); - if (IS_ERR(clk)) { + if (IS_ERR(clk_hw)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; @@ -275,14 +266,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, /* register a clock lookup only if a clock alias is specified */ if (list->alias) { - ret = clk_register_clkdev(clk, list->alias, + ret = clk_hw_register_clkdev(clk_hw, list->alias, list->dev_name); if (ret) pr_err("%s: failed to register lookup %s\n", __func__, list->alias); } - samsung_clk_add_lookup(ctx, clk, list->id); + samsung_clk_add_lookup(ctx, clk_hw, list->id); } } diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index da3bdebabf1e..b8ca0dd3a38b 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -16,18 +16,17 @@ #include <linux/clk-provider.h> #include "clk-pll.h" -struct clk; - /** * struct samsung_clk_provider: information about clock provider * @reg_base: virtual address for the register base. - * @clk_data: holds clock related data like clk* and number of clocks. * @lock: maintains exclusion between callbacks for a given clock-provider. + * @clk_data: holds clock related data like clk_hw* and number of clocks. */ struct samsung_clk_provider { void __iomem *reg_base; - struct clk_onecell_data clk_data; spinlock_t lock; + /* clk_data must be the last entry due to variable lenght 'hws' array */ + struct clk_hw_onecell_data clk_data; }; /** @@ -367,7 +366,7 @@ extern void __init samsung_clk_of_register_fixed_ext( const struct of_device_id *clk_matches); extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, - struct clk *clk, unsigned int id); + struct clk_hw *clk_hw, unsigned int id); extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, const struct samsung_clock_alias *list, diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index 5c476f966a72..5372bf8be5e6 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c @@ -243,7 +243,7 @@ static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb", static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb", 0x060, BIT(6), 0); static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb", - 0x060, BIT(6), 0); + 0x060, BIT(7), 0); static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb", 0x060, BIT(8), 0); static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb", diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index 794130402c8d..58b54b814a6d 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -1,6 +1,5 @@ # Makefile for Versatile-specific clocks obj-$(CONFIG_ICST) += icst.o clk-icst.o clk-versatile.o obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o -obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o obj-$(CONFIG_CLK_SP810) += clk-sp810.o obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk-vexpress-osc.o diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c deleted file mode 100644 index 6fdfee3232f4..000000000000 --- a/drivers/clk/versatile/clk-realview.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Clock driver for the ARM RealView boards - * Copyright (C) 2012 Linus Walleij - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clkdev.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/clk-provider.h> - -#include "icst.h" -#include "clk-icst.h" - -#define REALVIEW_SYS_OSC0_OFFSET 0x0C -#define REALVIEW_SYS_OSC1_OFFSET 0x10 -#define REALVIEW_SYS_OSC2_OFFSET 0x14 -#define REALVIEW_SYS_OSC3_OFFSET 0x18 -#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ -#define REALVIEW_SYS_LOCK_OFFSET 0x20 - -/* - * Implementation of the ARM RealView clock trees. - */ - -static const struct icst_params realview_oscvco_params = { - .ref = 24000000, - .vco_max = ICST307_VCO_MAX, - .vco_min = ICST307_VCO_MIN, - .vd_min = 4 + 8, - .vd_max = 511 + 8, - .rd_min = 1 + 2, - .rd_max = 127 + 2, - .s2div = icst307_s2div, - .idx2s = icst307_idx2s, -}; - -static const struct clk_icst_desc realview_osc0_desc __initconst = { - .params = &realview_oscvco_params, - .vco_offset = REALVIEW_SYS_OSC0_OFFSET, - .lock_offset = REALVIEW_SYS_LOCK_OFFSET, -}; - -static const struct clk_icst_desc realview_osc4_desc __initconst = { - .params = &realview_oscvco_params, - .vco_offset = REALVIEW_SYS_OSC4_OFFSET, - .lock_offset = REALVIEW_SYS_LOCK_OFFSET, -}; - -/* - * realview_clk_init() - set up the RealView clock tree - */ -void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) -{ - struct clk *clk; - - /* APB clock dummy */ - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - - /* 24 MHz clock */ - clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, 0, 24000000); - clk_register_clkdev(clk, NULL, "dev:uart0"); - clk_register_clkdev(clk, NULL, "dev:uart1"); - clk_register_clkdev(clk, NULL, "dev:uart2"); - clk_register_clkdev(clk, NULL, "fpga:kmi0"); - clk_register_clkdev(clk, NULL, "fpga:kmi1"); - clk_register_clkdev(clk, NULL, "fpga:mmc0"); - clk_register_clkdev(clk, NULL, "dev:ssp0"); - if (is_pb1176) { - /* - * UART3 is on the dev chip in PB1176 - * UART4 only exists in PB1176 - */ - clk_register_clkdev(clk, NULL, "dev:uart3"); - clk_register_clkdev(clk, NULL, "dev:uart4"); - } else - clk_register_clkdev(clk, NULL, "fpga:uart3"); - - - /* 1 MHz clock */ - clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, 0, 1000000); - clk_register_clkdev(clk, NULL, "sp804"); - - /* ICST VCO clock */ - if (is_pb1176) - clk = icst_clk_register(NULL, &realview_osc0_desc, - "osc0", NULL, sysbase); - else - clk = icst_clk_register(NULL, &realview_osc4_desc, - "osc4", NULL, sysbase); - - clk_register_clkdev(clk, NULL, "dev:clcd"); - clk_register_clkdev(clk, NULL, "issp:clcd"); -} diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h index 6fd21c291416..2740ae0424a9 100644 --- a/include/dt-bindings/clock/exynos5420.h +++ b/include/dt-bindings/clock/exynos5420.h @@ -217,6 +217,9 @@ #define CLK_MOUT_MCLK_CDREX 654 #define CLK_MOUT_BPLL 655 #define CLK_MOUT_MX_MSPLL_CCORE 656 +#define CLK_MOUT_EPLL 657 +#define CLK_MOUT_MAU_EPLL 658 +#define CLK_MOUT_USER_MAU_EPLL 659 /* divider clocks */ #define CLK_DOUT_PIXEL 768 diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h index 3190e30b9398..e3e9f7919c31 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h @@ -5,7 +5,6 @@ #ifndef __GXBB_CLKC_H #define __GXBB_CLKC_H -#define CLKID_CPUCLK 1 #define CLKID_HDMI_PLL 2 #define CLKID_FCLK_DIV2 4 #define CLKID_FCLK_DIV3 5 @@ -13,24 +12,30 @@ #define CLKID_GP0_PLL 9 #define CLKID_CLK81 12 #define CLKID_MPLL2 15 +#define CLKID_SPICC 21 #define CLKID_I2C 22 #define CLKID_SAR_ADC 23 #define CLKID_RNG0 25 +#define CLKID_UART0 26 #define CLKID_SPI 34 #define CLKID_ETH 36 #define CLKID_AIU_GLUE 38 +#define CLKID_IEC958 39 #define CLKID_I2S_OUT 40 #define CLKID_MIXER_IFACE 44 #define CLKID_AIU 47 +#define CLKID_UART1 48 #define CLKID_USB0 50 #define CLKID_USB1 51 #define CLKID_USB 55 #define CLKID_HDMI_PCLK 63 #define CLKID_USB1_DDR_BRIDGE 64 #define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_UART2 68 #define CLKID_SANA 69 #define CLKID_GCLK_VENCI_INT0 77 #define CLKID_AOCLK_GATE 80 +#define CLKID_IEC958_GATE 81 #define CLKID_AO_I2C 93 #define CLKID_SD_EMMC_A 94 #define CLKID_SD_EMMC_B 95 @@ -42,5 +47,8 @@ #define CLKID_MALI_1_SEL 103 #define CLKID_MALI_1 105 #define CLKID_MALI 106 +#define CLKID_CTS_AMCLK 107 +#define CLKID_CTS_MCLK_I958 110 +#define CLKID_CTS_I958 113 #endif /* __GXBB_CLKC_H */ diff --git a/include/dt-bindings/clock/r8a7790-cpg-mssr.h b/include/dt-bindings/clock/r8a7790-cpg-mssr.h new file mode 100644 index 000000000000..1625b8bf3482 --- /dev/null +++ b/include/dt-bindings/clock/r8a7790-cpg-mssr.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* r8a7790 CPG Core Clocks */ +#define R8A7790_CLK_Z 0 +#define R8A7790_CLK_Z2 1 +#define R8A7790_CLK_ZG 2 +#define R8A7790_CLK_ZTR 3 +#define R8A7790_CLK_ZTRD2 4 +#define R8A7790_CLK_ZT 5 +#define R8A7790_CLK_ZX 6 +#define R8A7790_CLK_ZS 7 +#define R8A7790_CLK_HP 8 +#define R8A7790_CLK_I 9 +#define R8A7790_CLK_B 10 +#define R8A7790_CLK_LB 11 +#define R8A7790_CLK_P 12 +#define R8A7790_CLK_CL 13 +#define R8A7790_CLK_M2 14 +#define R8A7790_CLK_ADSP 15 +#define R8A7790_CLK_IMP 16 +#define R8A7790_CLK_ZB3 17 +#define R8A7790_CLK_ZB3D2 18 +#define R8A7790_CLK_DDR 19 +#define R8A7790_CLK_SDH 20 +#define R8A7790_CLK_SD0 21 +#define R8A7790_CLK_SD1 22 +#define R8A7790_CLK_SD2 23 +#define R8A7790_CLK_SD3 24 +#define R8A7790_CLK_MMC0 25 +#define R8A7790_CLK_MMC1 26 +#define R8A7790_CLK_MP 27 +#define R8A7790_CLK_SSP 28 +#define R8A7790_CLK_SSPRS 29 +#define R8A7790_CLK_QSPI 30 +#define R8A7790_CLK_CP 31 +#define R8A7790_CLK_RCAN 32 +#define R8A7790_CLK_R 33 +#define R8A7790_CLK_OSC 34 + +#endif /* __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/clock/r8a7791-cpg-mssr.h b/include/dt-bindings/clock/r8a7791-cpg-mssr.h new file mode 100644 index 000000000000..e8823410c01c --- /dev/null +++ b/include/dt-bindings/clock/r8a7791-cpg-mssr.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* r8a7791 CPG Core Clocks */ +#define R8A7791_CLK_Z 0 +#define R8A7791_CLK_ZG 1 +#define R8A7791_CLK_ZTR 2 +#define R8A7791_CLK_ZTRD2 3 +#define R8A7791_CLK_ZT 4 +#define R8A7791_CLK_ZX 5 +#define R8A7791_CLK_ZS 6 +#define R8A7791_CLK_HP 7 +#define R8A7791_CLK_I 8 +#define R8A7791_CLK_B 9 +#define R8A7791_CLK_LB 10 +#define R8A7791_CLK_P 11 +#define R8A7791_CLK_CL 12 +#define R8A7791_CLK_M2 13 +#define R8A7791_CLK_ADSP 14 +#define R8A7791_CLK_ZB3 15 +#define R8A7791_CLK_ZB3D2 16 +#define R8A7791_CLK_DDR 17 +#define R8A7791_CLK_SDH 18 +#define R8A7791_CLK_SD0 19 +#define R8A7791_CLK_SD2 20 +#define R8A7791_CLK_SD3 21 +#define R8A7791_CLK_MMC0 22 +#define R8A7791_CLK_MP 23 +#define R8A7791_CLK_SSP 24 +#define R8A7791_CLK_SSPRS 25 +#define R8A7791_CLK_QSPI 26 +#define R8A7791_CLK_CP 27 +#define R8A7791_CLK_RCAN 28 +#define R8A7791_CLK_R 29 +#define R8A7791_CLK_OSC 30 + +#endif /* __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/clock/r8a7792-cpg-mssr.h b/include/dt-bindings/clock/r8a7792-cpg-mssr.h new file mode 100644 index 000000000000..72ce85cb2f94 --- /dev/null +++ b/include/dt-bindings/clock/r8a7792-cpg-mssr.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* r8a7792 CPG Core Clocks */ +#define R8A7792_CLK_Z 0 +#define R8A7792_CLK_ZG 1 +#define R8A7792_CLK_ZTR 2 +#define R8A7792_CLK_ZTRD2 3 +#define R8A7792_CLK_ZT 4 +#define R8A7792_CLK_ZX 5 +#define R8A7792_CLK_ZS 6 +#define R8A7792_CLK_HP 7 +#define R8A7792_CLK_I 8 +#define R8A7792_CLK_B 9 +#define R8A7792_CLK_LB 10 +#define R8A7792_CLK_P 11 +#define R8A7792_CLK_CL 12 +#define R8A7792_CLK_M2 13 +#define R8A7792_CLK_IMP 14 +#define R8A7792_CLK_ZB3 15 +#define R8A7792_CLK_ZB3D2 16 +#define R8A7792_CLK_DDR 17 +#define R8A7792_CLK_SD 18 +#define R8A7792_CLK_MP 19 +#define R8A7792_CLK_QSPI 20 +#define R8A7792_CLK_CP 21 +#define R8A7792_CLK_CPEX 22 +#define R8A7792_CLK_RCAN 23 +#define R8A7792_CLK_R 24 +#define R8A7792_CLK_OSC 25 + +#endif /* __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/clock/r8a7793-cpg-mssr.h b/include/dt-bindings/clock/r8a7793-cpg-mssr.h new file mode 100644 index 000000000000..8809b0f62d61 --- /dev/null +++ b/include/dt-bindings/clock/r8a7793-cpg-mssr.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* r8a7793 CPG Core Clocks */ +#define R8A7793_CLK_Z 0 +#define R8A7793_CLK_ZG 1 +#define R8A7793_CLK_ZTR 2 +#define R8A7793_CLK_ZTRD2 3 +#define R8A7793_CLK_ZT 4 +#define R8A7793_CLK_ZX 5 +#define R8A7793_CLK_ZS 6 +#define R8A7793_CLK_HP 7 +#define R8A7793_CLK_I 8 +#define R8A7793_CLK_B 9 +#define R8A7793_CLK_LB 10 +#define R8A7793_CLK_P 11 +#define R8A7793_CLK_CL 12 +#define R8A7793_CLK_M2 13 +#define R8A7793_CLK_ADSP 14 +#define R8A7793_CLK_ZB3 15 +#define R8A7793_CLK_ZB3D2 16 +#define R8A7793_CLK_DDR 17 +#define R8A7793_CLK_SDH 18 +#define R8A7793_CLK_SD0 19 +#define R8A7793_CLK_SD2 20 +#define R8A7793_CLK_SD3 21 +#define R8A7793_CLK_MMC0 22 +#define R8A7793_CLK_MP 23 +#define R8A7793_CLK_SSP 24 +#define R8A7793_CLK_SSPRS 25 +#define R8A7793_CLK_QSPI 26 +#define R8A7793_CLK_CP 27 +#define R8A7793_CLK_RCAN 28 +#define R8A7793_CLK_R 29 +#define R8A7793_CLK_OSC 30 + +#endif /* __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/clock/r8a7794-cpg-mssr.h b/include/dt-bindings/clock/r8a7794-cpg-mssr.h new file mode 100644 index 000000000000..9d720311ae3a --- /dev/null +++ b/include/dt-bindings/clock/r8a7794-cpg-mssr.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* r8a7794 CPG Core Clocks */ +#define R8A7794_CLK_Z2 0 +#define R8A7794_CLK_ZG 1 +#define R8A7794_CLK_ZTR 2 +#define R8A7794_CLK_ZTRD2 3 +#define R8A7794_CLK_ZT 4 +#define R8A7794_CLK_ZX 5 +#define R8A7794_CLK_ZS 6 +#define R8A7794_CLK_HP 7 +#define R8A7794_CLK_I 8 +#define R8A7794_CLK_B 9 +#define R8A7794_CLK_LB 10 +#define R8A7794_CLK_P 11 +#define R8A7794_CLK_CL 12 +#define R8A7794_CLK_CP 13 +#define R8A7794_CLK_M2 14 +#define R8A7794_CLK_ADSP 15 +#define R8A7794_CLK_ZB3 16 +#define R8A7794_CLK_ZB3D2 17 +#define R8A7794_CLK_DDR 18 +#define R8A7794_CLK_SDH 19 +#define R8A7794_CLK_SD0 20 +#define R8A7794_CLK_SD2 21 +#define R8A7794_CLK_SD3 22 +#define R8A7794_CLK_MMC0 23 +#define R8A7794_CLK_MP 24 +#define R8A7794_CLK_QSPI 25 +#define R8A7794_CLK_CPEX 26 +#define R8A7794_CLK_RCAN 27 +#define R8A7794_CLK_R 28 +#define R8A7794_CLK_OSC 29 + +#endif /* __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/clock/rk3128-cru.h b/include/dt-bindings/clock/rk3128-cru.h new file mode 100644 index 000000000000..92894f4306cf --- /dev/null +++ b/include/dt-bindings/clock/rk3128-cru.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2017 Rockchip Electronics Co. Ltd. + * Author: Elaine <zhangqing@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H + +/* core clocks */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_CPLL 3 +#define PLL_GPLL 4 +#define ARMCLK 5 +#define PLL_GPLL_DIV2 6 +#define PLL_GPLL_DIV3 7 + +/* sclk gates (special clocks) */ +#define SCLK_SPI0 65 +#define SCLK_NANDC 67 +#define SCLK_SDMMC 68 +#define SCLK_SDIO 69 +#define SCLK_EMMC 71 +#define SCLK_UART0 77 +#define SCLK_UART1 78 +#define SCLK_UART2 79 +#define SCLK_I2S0 80 +#define SCLK_I2S1 81 +#define SCLK_SPDIF 83 +#define SCLK_TIMER0 85 +#define SCLK_TIMER1 86 +#define SCLK_TIMER2 87 +#define SCLK_TIMER3 88 +#define SCLK_TIMER4 89 +#define SCLK_TIMER5 90 +#define SCLK_SARADC 91 +#define SCLK_I2S_OUT 113 +#define SCLK_SDMMC_DRV 114 +#define SCLK_SDIO_DRV 115 +#define SCLK_EMMC_DRV 117 +#define SCLK_SDMMC_SAMPLE 118 +#define SCLK_SDIO_SAMPLE 119 +#define SCLK_EMMC_SAMPLE 121 +#define SCLK_VOP 122 +#define SCLK_MAC_SRC 124 +#define SCLK_MAC 126 +#define SCLK_MAC_REFOUT 127 +#define SCLK_MAC_REF 128 +#define SCLK_MAC_RX 129 +#define SCLK_MAC_TX 130 +#define SCLK_HEVC_CORE 134 +#define SCLK_RGA 135 +#define SCLK_CRYPTO 138 +#define SCLK_TSP 139 +#define SCLK_OTGPHY0 142 +#define SCLK_OTGPHY1 143 +#define SCLK_DDRC 144 +#define SCLK_PVTM_FUNC 145 +#define SCLK_PVTM_CORE 146 +#define SCLK_PVTM_GPU 147 +#define SCLK_MIPI_24M 148 +#define SCLK_PVTM 149 +#define SCLK_CIF_SRC 150 +#define SCLK_CIF_OUT_SRC 151 +#define SCLK_CIF_OUT 152 +#define SCLK_SFC 153 +#define SCLK_USB480M 154 + +/* dclk gates */ +#define DCLK_VOP 190 +#define DCLK_EBC 191 + +/* aclk gates */ +#define ACLK_VIO0 192 +#define ACLK_VIO1 193 +#define ACLK_DMAC 194 +#define ACLK_CPU 195 +#define ACLK_VEPU 196 +#define ACLK_VDPU 197 +#define ACLK_CIF 198 +#define ACLK_IEP 199 +#define ACLK_LCDC0 204 +#define ACLK_RGA 205 +#define ACLK_PERI 210 +#define ACLK_VOP 211 +#define ACLK_GMAC 212 +#define ACLK_GPU 213 + +/* pclk gates */ +#define PCLK_SARADC 318 +#define PCLK_WDT 319 +#define PCLK_GPIO0 320 +#define PCLK_GPIO1 321 +#define PCLK_GPIO2 322 +#define PCLK_GPIO3 323 +#define PCLK_VIO_H2P 324 +#define PCLK_MIPI 325 +#define PCLK_EFUSE 326 +#define PCLK_HDMI 327 +#define PCLK_ACODEC 328 +#define PCLK_GRF 329 +#define PCLK_I2C0 332 +#define PCLK_I2C1 333 +#define PCLK_I2C2 334 +#define PCLK_I2C3 335 +#define PCLK_SPI0 338 +#define PCLK_UART0 341 +#define PCLK_UART1 342 +#define PCLK_UART2 343 +#define PCLK_TSADC 344 +#define PCLK_PWM 350 +#define PCLK_TIMER 353 +#define PCLK_CPU 354 +#define PCLK_PERI 363 +#define PCLK_GMAC 367 +#define PCLK_PMU_PRE 368 +#define PCLK_SIM_CARD 369 + +/* hclk gates */ +#define HCLK_SPDIF 440 +#define HCLK_GPS 441 +#define HCLK_USBHOST 442 +#define HCLK_I2S_8CH 443 +#define HCLK_I2S_2CH 444 +#define HCLK_VOP 452 +#define HCLK_NANDC 453 +#define HCLK_SDMMC 456 +#define HCLK_SDIO 457 +#define HCLK_EMMC 459 +#define HCLK_CPU 460 +#define HCLK_VEPU 461 +#define HCLK_VDPU 462 +#define HCLK_LCDC0 463 +#define HCLK_EBC 465 +#define HCLK_VIO 466 +#define HCLK_RGA 467 +#define HCLK_IEP 468 +#define HCLK_VIO_H2P 469 +#define HCLK_CIF 470 +#define HCLK_HOST2 473 +#define HCLK_OTG 474 +#define HCLK_TSP 475 +#define HCLK_CRYPTO 476 +#define HCLK_PERI 478 + +#define CLK_NR_CLKS (HCLK_PERI + 1) + +/* soft-reset indices */ +#define SRST_CORE0_PO 0 +#define SRST_CORE1_PO 1 +#define SRST_CORE2_PO 2 +#define SRST_CORE3_PO 3 +#define SRST_CORE0 4 +#define SRST_CORE1 5 +#define SRST_CORE2 6 +#define SRST_CORE3 7 +#define SRST_CORE0_DBG 8 +#define SRST_CORE1_DBG 9 +#define SRST_CORE2_DBG 10 +#define SRST_CORE3_DBG 11 +#define SRST_TOPDBG 12 +#define SRST_ACLK_CORE 13 +#define SRST_STRC_SYS_A 14 +#define SRST_L2C 15 + +#define SRST_CPUSYS_H 18 +#define SRST_AHB2APBSYS_H 19 +#define SRST_SPDIF 20 +#define SRST_INTMEM 21 +#define SRST_ROM 22 +#define SRST_PERI_NIU 23 +#define SRST_I2S_2CH 24 +#define SRST_I2S_8CH 25 +#define SRST_GPU_PVTM 26 +#define SRST_FUNC_PVTM 27 +#define SRST_CORE_PVTM 29 +#define SRST_EFUSE_P 30 +#define SRST_ACODEC_P 31 + +#define SRST_GPIO0 32 +#define SRST_GPIO1 33 +#define SRST_GPIO2 34 +#define SRST_GPIO3 35 +#define SRST_MIPIPHY_P 36 +#define SRST_UART0 39 +#define SRST_UART1 40 +#define SRST_UART2 41 +#define SRST_I2C0 43 +#define SRST_I2C1 44 +#define SRST_I2C2 45 +#define SRST_I2C3 46 +#define SRST_SFC 47 + +#define SRST_PWM 48 +#define SRST_DAP_PO 50 +#define SRST_DAP 51 +#define SRST_DAP_SYS 52 +#define SRST_CRYPTO 53 +#define SRST_GRF 55 +#define SRST_GMAC 56 +#define SRST_PERIPH_SYS_A 57 +#define SRST_PERIPH_SYS_H 58 +#define SRST_PERIPH_SYS_P 59 +#define SRST_SMART_CARD 60 +#define SRST_CPU_PERI 61 +#define SRST_EMEM_PERI 62 +#define SRST_USB_PERI 63 + +#define SRST_DMA 64 +#define SRST_GPS 67 +#define SRST_NANDC 68 +#define SRST_USBOTG0 69 +#define SRST_OTGC0 71 +#define SRST_USBOTG1 72 +#define SRST_OTGC1 74 +#define SRST_DDRMSCH 79 + +#define SRST_SDMMC 81 +#define SRST_SDIO 82 +#define SRST_EMMC 83 +#define SRST_SPI 84 +#define SRST_WDT 86 +#define SRST_SARADC 87 +#define SRST_DDRPHY 88 +#define SRST_DDRPHY_P 89 +#define SRST_DDRCTRL 90 +#define SRST_DDRCTRL_P 91 +#define SRST_TSP 92 +#define SRST_TSP_CLKIN 93 +#define SRST_HOST0_ECHI 94 + +#define SRST_HDMI_P 96 +#define SRST_VIO_ARBI_H 97 +#define SRST_VIO0_A 98 +#define SRST_VIO_BUS_H 99 +#define SRST_VOP_A 100 +#define SRST_VOP_H 101 +#define SRST_VOP_D 102 +#define SRST_UTMI0 103 +#define SRST_UTMI1 104 +#define SRST_USBPOR 105 +#define SRST_IEP_A 106 +#define SRST_IEP_H 107 +#define SRST_RGA_A 108 +#define SRST_RGA_H 109 +#define SRST_CIF0 110 +#define SRST_PMU 111 + +#define SRST_VCODEC_A 112 +#define SRST_VCODEC_H 113 +#define SRST_VIO1_A 114 +#define SRST_HEVC_CORE 115 +#define SRST_VCODEC_NIU_A 116 +#define SRST_PMU_NIU_P 117 +#define SRST_LCDC0_S 119 +#define SRST_GPU 120 +#define SRST_GPU_NIU_A 122 +#define SRST_EBC_A 123 +#define SRST_EBC_H 124 + +#define SRST_CORE_DBG 128 +#define SRST_DBG_P 129 +#define SRST_TIMER0 130 +#define SRST_TIMER1 131 +#define SRST_TIMER2 132 +#define SRST_TIMER3 133 +#define SRST_TIMER4 134 +#define SRST_TIMER5 135 +#define SRST_VIO_H2P 136 +#define SRST_VIO_MIPI_DSI 137 + +#endif diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index b27e2b1a65e3..56f841c22801 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -61,6 +61,17 @@ #define SCLK_MAC_TX 130 #define SCLK_MAC_PHY 131 #define SCLK_MAC_OUT 132 +#define SCLK_VDEC_CABAC 133 +#define SCLK_VDEC_CORE 134 +#define SCLK_RGA 135 +#define SCLK_HDCP 136 +#define SCLK_HDMI_CEC 137 +#define SCLK_CRYPTO 138 +#define SCLK_TSP 139 +#define SCLK_HSADC 140 +#define SCLK_WIFI 141 +#define SCLK_OTGPHY0 142 +#define SCLK_OTGPHY1 143 /* dclk gates */ #define DCLK_VOP 190 @@ -68,15 +79,32 @@ /* aclk gates */ #define ACLK_DMAC 194 +#define ACLK_CPU 195 +#define ACLK_VPU_PRE 196 +#define ACLK_RKVDEC_PRE 197 +#define ACLK_RGA_PRE 198 +#define ACLK_IEP_PRE 199 +#define ACLK_HDCP_PRE 200 +#define ACLK_VOP_PRE 201 +#define ACLK_VPU 202 +#define ACLK_RKVDEC 203 +#define ACLK_IEP 204 +#define ACLK_RGA 205 +#define ACLK_HDCP 206 #define ACLK_PERI 210 #define ACLK_VOP 211 #define ACLK_GMAC 212 +#define ACLK_GPU 213 /* pclk gates */ #define PCLK_GPIO0 320 #define PCLK_GPIO1 321 #define PCLK_GPIO2 322 #define PCLK_GPIO3 323 +#define PCLK_VIO_H2P 324 +#define PCLK_HDCP 325 +#define PCLK_EFUSE_1024 326 +#define PCLK_EFUSE_256 327 #define PCLK_GRF 329 #define PCLK_I2C0 332 #define PCLK_I2C1 333 @@ -89,6 +117,7 @@ #define PCLK_TSADC 344 #define PCLK_PWM 350 #define PCLK_TIMER 353 +#define PCLK_CPU 354 #define PCLK_PERI 363 #define PCLK_HDMI_CTRL 364 #define PCLK_HDMI_PHY 365 @@ -104,6 +133,24 @@ #define HCLK_SDMMC 456 #define HCLK_SDIO 457 #define HCLK_EMMC 459 +#define HCLK_CPU 460 +#define HCLK_VPU_PRE 461 +#define HCLK_RKVDEC_PRE 462 +#define HCLK_VIO_PRE 463 +#define HCLK_VPU 464 +#define HCLK_RKVDEC 465 +#define HCLK_VIO 466 +#define HCLK_RGA 467 +#define HCLK_IEP 468 +#define HCLK_VIO_H2P 469 +#define HCLK_HDCP_MMU 470 +#define HCLK_HOST0 471 +#define HCLK_HOST1 472 +#define HCLK_HOST2 473 +#define HCLK_OTG 474 +#define HCLK_TSP 475 +#define HCLK_M_CRYPTO 476 +#define HCLK_S_CRYPTO 477 #define HCLK_PERI 478 #define CLK_NR_CLKS (HCLK_PERI + 1) diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h index 220a60f20d3b..22cb1dfa9004 100644 --- a/include/dt-bindings/clock/rk3399-cru.h +++ b/include/dt-bindings/clock/rk3399-cru.h @@ -132,6 +132,8 @@ #define SCLK_RMII_SRC 166 #define SCLK_PCIEPHY_REF100M 167 #define SCLK_DDRC 168 +#define SCLK_TESTCLKOUT1 169 +#define SCLK_TESTCLKOUT2 170 #define DCLK_VOP0 180 #define DCLK_VOP1 181 diff --git a/include/linux/clk.h b/include/linux/clk.h index 024cd07870d0..91bd464f4c9b 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -77,6 +77,21 @@ struct clk_notifier_data { unsigned long new_rate; }; +/** + * struct clk_bulk_data - Data used for bulk clk operations. + * + * @id: clock consumer ID + * @clk: struct clk * to store the associated clock + * + * The CLK APIs provide a series of clk_bulk_() API calls as + * a convenience to consumers which require multiple clks. This + * structure is used to manage data for these calls. + */ +struct clk_bulk_data { + const char *id; + struct clk *clk; +}; + #ifdef CONFIG_COMMON_CLK /** @@ -185,12 +200,20 @@ static inline bool clk_is_match(const struct clk *p, const struct clk *q) */ #ifdef CONFIG_HAVE_CLK_PREPARE int clk_prepare(struct clk *clk); +int __must_check clk_bulk_prepare(int num_clks, + const struct clk_bulk_data *clks); #else static inline int clk_prepare(struct clk *clk) { might_sleep(); return 0; } + +static inline int clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks) +{ + might_sleep(); + return 0; +} #endif /** @@ -204,11 +227,16 @@ static inline int clk_prepare(struct clk *clk) */ #ifdef CONFIG_HAVE_CLK_PREPARE void clk_unprepare(struct clk *clk); +void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); #else static inline void clk_unprepare(struct clk *clk) { might_sleep(); } +static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks) +{ + might_sleep(); +} #endif #ifdef CONFIG_HAVE_CLK @@ -230,6 +258,44 @@ static inline void clk_unprepare(struct clk *clk) struct clk *clk_get(struct device *dev, const char *id); /** + * clk_bulk_get - lookup and obtain a number of references to clock producer. + * @dev: device for clock "consumer" + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * This helper function allows drivers to get several clk consumers in one + * operation. If any of the clk cannot be acquired then any clks + * that were obtained will be freed before returning to the caller. + * + * Returns 0 if all clocks specified in clk_bulk_data table are obtained + * successfully, or valid IS_ERR() condition containing errno. + * The implementation uses @dev and @clk_bulk_data.id to determine the + * clock consumer, and thereby the clock producer. + * The clock returned is stored in each @clk_bulk_data.clk field. + * + * Drivers must assume that the clock source is not enabled. + * + * clk_bulk_get should not be called from within interrupt context. + */ +int __must_check clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks); + +/** + * devm_clk_bulk_get - managed get multiple clk consumers + * @dev: device for clock "consumer" + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * Return 0 on success, an errno on failure. + * + * This helper function allows drivers to get several clk + * consumers in one operation with management, the clks will + * automatically be freed when the device is unbound. + */ +int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks); + +/** * devm_clk_get - lookup and obtain a managed reference to a clock producer. * @dev: device for clock "consumer" * @id: clock consumer ID @@ -279,6 +345,18 @@ struct clk *devm_get_clk_from_child(struct device *dev, int clk_enable(struct clk *clk); /** + * clk_bulk_enable - inform the system when the set of clks should be running. + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * May be called from atomic contexts. + * + * Returns success (0) or negative errno. + */ +int __must_check clk_bulk_enable(int num_clks, + const struct clk_bulk_data *clks); + +/** * clk_disable - inform the system when the clock source is no longer required. * @clk: clock source * @@ -295,6 +373,24 @@ int clk_enable(struct clk *clk); void clk_disable(struct clk *clk); /** + * clk_bulk_disable - inform the system when the set of clks is no + * longer required. + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * Inform the system that a set of clks is no longer required by + * a driver and may be shut down. + * + * May be called from atomic contexts. + * + * Implementation detail: if the set of clks is shared between + * multiple drivers, clk_bulk_enable() calls must be balanced by the + * same number of clk_bulk_disable() calls for the clock source to be + * disabled. + */ +void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks); + +/** * clk_get_rate - obtain the current clock rate (in Hz) for a clock source. * This is only valid once the clock source has been enabled. * @clk: clock source @@ -314,6 +410,19 @@ unsigned long clk_get_rate(struct clk *clk); void clk_put(struct clk *clk); /** + * clk_bulk_put - "free" the clock source + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * Note: drivers must ensure that all clk_bulk_enable calls made on this + * clock source are balanced by clk_bulk_disable calls prior to calling + * this function. + * + * clk_bulk_put should not be called from within interrupt context. + */ +void clk_bulk_put(int num_clks, struct clk_bulk_data *clks); + +/** * devm_clk_put - "free" a managed clock source * @dev: device used to acquire the clock * @clk: clock source acquired with devm_clk_get() @@ -445,11 +554,23 @@ static inline struct clk *clk_get(struct device *dev, const char *id) return NULL; } +static inline int clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + static inline struct clk *devm_clk_get(struct device *dev, const char *id) { return NULL; } +static inline int devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + static inline struct clk *devm_get_clk_from_child(struct device *dev, struct device_node *np, const char *con_id) { @@ -458,6 +579,8 @@ static inline struct clk *devm_get_clk_from_child(struct device *dev, static inline void clk_put(struct clk *clk) {} +static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} + static inline void devm_clk_put(struct device *dev, struct clk *clk) {} static inline int clk_enable(struct clk *clk) @@ -465,8 +588,17 @@ static inline int clk_enable(struct clk *clk) return 0; } +static inline int clk_bulk_enable(int num_clks, struct clk_bulk_data *clks) +{ + return 0; +} + static inline void clk_disable(struct clk *clk) {} + +static inline void clk_bulk_disable(int num_clks, + struct clk_bulk_data *clks) {} + static inline unsigned long clk_get_rate(struct clk *clk) { return 0; @@ -539,6 +671,10 @@ static inline struct clk *of_clk_get_by_name(struct device_node *np, { return ERR_PTR(-ENOENT); } +static inline struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) +{ + return ERR_PTR(-ENOENT); +} #endif #endif diff --git a/include/linux/platform_data/clk-realview.h b/include/linux/platform_data/clk-realview.h deleted file mode 100644 index 2e426a7dbc51..000000000000 --- a/include/linux/platform_data/clk-realview.h +++ /dev/null @@ -1 +0,0 @@ -void realview_clk_init(void __iomem *sysbase, bool is_pb1176); |