The clk changes for this release cycle are mostly dominated by
new device support in terms of LoC, but there has been some cleanup in the core as well as the usual minor clk additions to various drivers. Core: - parent tracking has been simplified - CLK_IS_ROOT is now a no-op flag, cleaning up drivers has started - of_clk_init() doesn't consider disabled DT nodes anymore - clk_unregister() had an error path bug squashed - of_clk_get_parent_count() has been fixed to only return unsigned ints - HAVE_MACH_CLKDEV is removed now that the last arch user (ARM) is gone New Drivers: - NXP LPC18xx creg - QCOM IPQ4019 GCC - TI dm814x ADPLL - i.MX6QP Updates: - Cyngus audio clks found on Broadcom iProc devices - Non-critical fixes for BCM2385 PLLs - Samsung exynos5433 updates for clk id errors, HDMI support, suspend/resume simplifications - USB, CAN, LVDS, and FCP clks on shmobile devices - sunxi got support for more clks on new SoCs and went through a minor refactoring/rewrite to use a simpler factor clk construct - rockchip added some more clk ids and added suport for fraction dividers - QCOM GDSCs in msm8996 - A new devm helper to make adding custom actions simpler (acked by Greg) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABCAAGBQJW8fPZAAoJENidgRMleOc9sc0P/2b4k8FiFwjMXiiXI1rcEjiz ZjeVxzyAcwBiYoL8a2XONd+pihjLNcAbDbjk8SGUzmKDDz7elQbrhby/6o1dPlW/ fQEQFa8Xa8zhZgidO1AFc1DmIcPg/u/Z58wHbjIcqDjvzKA63213Ud34NJsRtF6y +EJrIUZiTtj5q1pJgDmqlOv6ImmQtgW/AN51vNXCNNCyS9OsSgQm0DK5/f485HNc 2y5NE5hpijso69HFet5chuT3DiDLz/0dxmgCm/w9CRRzkHxYl3lxV/v07B+rZBo5 cWplFfvJqX7PvQtcP0sPPzZUfGT/vOeTboWprQwI4R3RObS18xLqlq6DEvOTmnqW Jh+9uNBq4+kwSz5GcYjpwvj7+W0FPgIaBVRHrEW9qeXkgDpYloPtnEt8C8GmO6Bt O0bgIzETq9mnRTA+VesIfjmTa4IYRDDUoDwGTw5CnW3jaZmtYJh8GhgZulMfPfyK vfWQkY2OesXFwct0rU8tFiswTPeTRgXqL3AsPYjTPAHx1kfBpvfOQTCzzT7eSBr7 jykd9EXsXrYb/rpIxW7j6KjPpaWu+EouK06wc4TIBGrrWVTIV0ZvybzOBgf0FnpS UDx87OyQb8x9TDMrfKf6bmJyly8y1dXkutFYY4XKIGUydlXIf0kn7AnIXW6SR7mX fTEdLFMZ03ViCojtah5r =bZFY -----END PGP SIGNATURE----- Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Stephen Boyd: "The clk changes for this release cycle are mostly dominated by new device support in terms of LoC, but there has been some cleanup in the core as well as the usual minor clk additions to various drivers. Core: - parent tracking has been simplified - CLK_IS_ROOT is now a no-op flag, cleaning up drivers has started - of_clk_init() doesn't consider disabled DT nodes anymore - clk_unregister() had an error path bug squashed - of_clk_get_parent_count() has been fixed to only return unsigned ints - HAVE_MACH_CLKDEV is removed now that the last arch user (ARM) is gone New Drivers: - NXP LPC18xx creg - QCOM IPQ4019 GCC - TI dm814x ADPLL - i.MX6QP Updates: - Cyngus audio clks found on Broadcom iProc devices - Non-critical fixes for BCM2385 PLLs - Samsung exynos5433 updates for clk id errors, HDMI support, suspend/resume simplifications - USB, CAN, LVDS, and FCP clks on shmobile devices - sunxi got support for more clks on new SoCs and went through a minor refactoring/rewrite to use a simpler factor clk construct - rockchip added some more clk ids and added suport for fraction dividers - QCOM GDSCs in msm8996 - A new devm helper to make adding custom actions simpler (acked by Greg)" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (197 commits) clk: bcm2835: fix check of error code returned by devm_ioremap_resource() clk: renesas: div6: use RENESAS for #define clk: renesas: Rename header file renesas.h clk: max77{686,802}: Remove CLK_IS_ROOT clk: versatile: Remove CLK_IS_ROOT clk: sunxi: Remove use of variable length array clk: fixed-rate: Remove CLK_IS_ROOT clk: qcom: Remove CLK_IS_ROOT doc: dt: add documentation for lpc1850-creg-clk driver clk: add lpc18xx creg clk driver clk: lpc32xx: fix compilation warning clk: xgene: Add missing parenthesis when clearing divider value clk: mb86s7x: Remove CLK_IS_ROOT clk: x86: Remove clkdev.h and clk.h includes clk: x86: Remove CLK_IS_ROOT clk: mvebu: Remove CLK_IS_ROOT clk: renesas: move drivers to renesas directory clk: si5{14,351,70}: Remove CLK_IS_ROOT clk: scpi: Remove CLK_IS_ROOT clk: s2mps11: Remove CLK_IS_ROOT ...
This commit is contained in:
commit
33c1f638a0
@ -8,7 +8,10 @@ Required properties:
|
||||
- compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a".
|
||||
- #clock-cells : from common clock binding; Should always be set to 0.
|
||||
- reg : Address and length of the axi-clkgen register set.
|
||||
- clocks : Phandle and clock specifier for the parent clock.
|
||||
- clocks : Phandle and clock specifier for the parent clock(s). This must
|
||||
either reference one clock if only the first clock input is connected or two
|
||||
if both clock inputs are connected. For the later case the clock connected
|
||||
to the first input must be specified first.
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : From common clock binding.
|
||||
|
@ -92,6 +92,7 @@ PLL and leaf clock compatible strings for Cygnus are:
|
||||
"brcm,cygnus-lcpll0"
|
||||
"brcm,cygnus-mipipll"
|
||||
"brcm,cygnus-asiu-clk"
|
||||
"brcm,cygnus-audiopll"
|
||||
|
||||
The following table defines the set of PLL/clock index and ID for Cygnus.
|
||||
These clock IDs are defined in:
|
||||
@ -131,6 +132,11 @@ These clock IDs are defined in:
|
||||
ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED
|
||||
ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED
|
||||
|
||||
audiopll crystal 0 BCM_CYGNUS_AUDIOPLL
|
||||
ch0_audio audiopll 1 BCM_CYGNUS_AUDIOPLL_CH0
|
||||
ch1_audio audiopll 2 BCM_CYGNUS_AUDIOPLL_CH1
|
||||
ch2_audio audiopll 3 BCM_CYGNUS_AUDIOPLL_CH2
|
||||
|
||||
Northstar and Northstar Plus
|
||||
------
|
||||
PLL and leaf clock compatible strings for Northstar and Northstar Plus are:
|
||||
|
52
Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt
Normal file
52
Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt
Normal file
@ -0,0 +1,52 @@
|
||||
* NXP LPC1850 CREG clocks
|
||||
|
||||
The NXP LPC18xx/43xx CREG (Configuration Registers) block contains
|
||||
control registers for two low speed clocks. One of the clocks is a
|
||||
32 kHz oscillator driver with power up/down and clock gating. Next
|
||||
is a fixed divider that creates a 1 kHz clock from the 32 kHz osc.
|
||||
|
||||
These clocks are used by the RTC and the Event Router peripherials.
|
||||
The 32 kHz can also be routed to other peripherials to enable low
|
||||
power modes.
|
||||
|
||||
This binding uses the common clock binding:
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible:
|
||||
Should be "nxp,lpc1850-creg-clk"
|
||||
- #clock-cells:
|
||||
Shall have value <1>.
|
||||
- clocks:
|
||||
Shall contain a phandle to the fixed 32 kHz crystal.
|
||||
|
||||
The creg-clk node must be a child of the creg syscon node.
|
||||
|
||||
The following clocks are available from the clock node.
|
||||
|
||||
Clock ID Name
|
||||
0 1 kHz clock
|
||||
1 32 kHz Oscillator
|
||||
|
||||
Example:
|
||||
soc {
|
||||
creg: syscon@40043000 {
|
||||
compatible = "nxp,lpc1850-creg", "syscon", "simple-mfd";
|
||||
reg = <0x40043000 0x1000>;
|
||||
|
||||
creg_clk: clock-controller {
|
||||
compatible = "nxp,lpc1850-creg-clk";
|
||||
clocks = <&xtal32>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
||||
};
|
||||
|
||||
rtc: rtc@40046000 {
|
||||
...
|
||||
clocks = <&creg_clk 0>, <&ccu1 CLK_CPU_BUS>;
|
||||
clock-names = "rtc", "reg";
|
||||
...
|
||||
};
|
||||
};
|
@ -7,6 +7,7 @@ Required properties :
|
||||
"qcom,gcc-apq8064"
|
||||
"qcom,gcc-apq8084"
|
||||
"qcom,gcc-ipq8064"
|
||||
"qcom,gcc-ipq4019"
|
||||
"qcom,gcc-msm8660"
|
||||
"qcom,gcc-msm8916"
|
||||
"qcom,gcc-msm8960"
|
||||
|
@ -61,7 +61,7 @@ Examples
|
||||
reg = <0 0xe6e88000 0 64>;
|
||||
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 310>;
|
||||
clock-names = "sci_ick";
|
||||
clock-names = "fck";
|
||||
dmas = <&dmac1 0x13>, <&dmac1 0x12>;
|
||||
dma-names = "tx", "rx";
|
||||
power-domains = <&cpg>;
|
||||
|
@ -18,6 +18,7 @@ Required properties:
|
||||
"allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock
|
||||
"allwinner,sun4i-a10-axi-clk" - for the AXI clock
|
||||
"allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23
|
||||
"allwinner,sun4i-a10-gates-clk" - for generic gates on all compatible SoCs
|
||||
"allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates
|
||||
"allwinner,sun4i-a10-ahb-clk" - for the AHB clock
|
||||
"allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
|
||||
@ -39,12 +40,14 @@ Required properties:
|
||||
"allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31
|
||||
"allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23
|
||||
"allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80
|
||||
"allwinner,sun8i-a83t-apb0-gates-clk" - for the APB0 gates on A83T
|
||||
"allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10
|
||||
"allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13
|
||||
"allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
|
||||
"allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31
|
||||
"allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
|
||||
"allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23
|
||||
"allwinner,sun8i-h3-apb0-gates-clk" - for the APB0 gates on H3
|
||||
"allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80
|
||||
"allwinner,sun4i-a10-apb1-clk" - for the APB1 clock
|
||||
"allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80
|
||||
@ -57,6 +60,7 @@ Required properties:
|
||||
"allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80
|
||||
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
|
||||
"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
|
||||
"allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T
|
||||
"allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3
|
||||
"allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80
|
||||
"allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10
|
||||
|
41
Documentation/devicetree/bindings/clock/ti/adpll.txt
Normal file
41
Documentation/devicetree/bindings/clock/ti/adpll.txt
Normal file
@ -0,0 +1,41 @@
|
||||
Binding for Texas Instruments ADPLL clock.
|
||||
|
||||
Binding status: Unstable - ABI compatibility may be broken in the future
|
||||
|
||||
This binding uses the common clock binding[1]. It assumes a
|
||||
register-mapped ADPLL with two to three selectable input clocks
|
||||
and three to four children.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be one of "ti,dm814-adpll-s-clock" or
|
||||
"ti,dm814-adpll-lj-clock" depending on the type of the ADPLL
|
||||
- #clock-cells : from common clock binding; shall be set to 1.
|
||||
- clocks : link phandles of parent clocks clkinp and clkinpulow, note
|
||||
that the adpll-s-clock also has an optional clkinphif
|
||||
- reg : address and length of the register set for controlling the ADPLL.
|
||||
|
||||
Examples:
|
||||
adpll_mpu_ck: adpll@40 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "ti,dm814-adpll-s-clock";
|
||||
reg = <0x40 0x40>;
|
||||
clocks = <&devosc_ck &devosc_ck &devosc_ck>;
|
||||
clock-names = "clkinp", "clkinpulow", "clkinphif";
|
||||
clock-output-names = "481c5040.adpll.dcoclkldo",
|
||||
"481c5040.adpll.clkout",
|
||||
"481c5040.adpll.clkoutx2",
|
||||
"481c5040.adpll.clkouthif";
|
||||
};
|
||||
|
||||
adpll_dsp_ck: adpll@80 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "ti,dm814-adpll-lj-clock";
|
||||
reg = <0x80 0x30>;
|
||||
clocks = <&devosc_ck &devosc_ck>;
|
||||
clock-names = "clkinp", "clkinpulow";
|
||||
clock-output-names = "481c5080.adpll.dcoclkldo",
|
||||
"481c5080.adpll.clkout",
|
||||
"481c5080.adpll.clkoutldo";
|
||||
};
|
@ -416,7 +416,7 @@
|
||||
status = "okay";
|
||||
|
||||
assigned-clocks = <&cru SCLK_USBPHY480M_SRC>;
|
||||
assigned-clock-parents = <&cru SCLK_OTGPHY0>;
|
||||
assigned-clock-parents = <&usbphy0>;
|
||||
dr_mode = "host";
|
||||
};
|
||||
|
||||
|
@ -32,6 +32,7 @@ config MACH_ARMADA_370
|
||||
select CPU_PJ4B
|
||||
select MACH_MVEBU_V7
|
||||
select PINCTRL_ARMADA_370
|
||||
select MVEBU_CLK_COREDIV
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support boards based
|
||||
on the Marvell Armada 370 SoC with device tree.
|
||||
@ -49,6 +50,7 @@ config MACH_ARMADA_375
|
||||
select HAVE_SMP
|
||||
select MACH_MVEBU_V7
|
||||
select PINCTRL_ARMADA_375
|
||||
select MVEBU_CLK_COREDIV
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support boards based
|
||||
on the Marvell Armada 375 SoC with device tree.
|
||||
@ -66,6 +68,7 @@ config MACH_ARMADA_38X
|
||||
select HAVE_SMP
|
||||
select MACH_MVEBU_V7
|
||||
select PINCTRL_ARMADA_38X
|
||||
select MVEBU_CLK_COREDIV
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support boards based
|
||||
on the Marvell Armada 380/385 SoC with device tree.
|
||||
|
@ -12,7 +12,7 @@
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -15,7 +15,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irqchip.h>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
|
@ -15,7 +15,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
|
@ -328,7 +328,6 @@ config LANTIQ
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select SWAP_IO_SPACE
|
||||
select BOOT_RAW
|
||||
select HAVE_MACH_CLKDEV
|
||||
select CLKDEV_LOOKUP
|
||||
select USE_OF
|
||||
select PINCTRL
|
||||
@ -590,7 +589,6 @@ config RALINK
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_SUPPORTS_MIPS16
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
select HAVE_MACH_CLKDEV
|
||||
select CLKDEV_LOOKUP
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select RESET_CONTROLLER
|
||||
|
@ -15,7 +15,6 @@ config PIC32MZDA
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select HAVE_MACH_CLKDEV
|
||||
select COMMON_CLK
|
||||
select CLKDEV_LOOKUP
|
||||
select LIBFDT
|
||||
|
@ -6,9 +6,6 @@ config CLKDEV_LOOKUP
|
||||
config HAVE_CLK_PREPARE
|
||||
bool
|
||||
|
||||
config HAVE_MACH_CLKDEV
|
||||
bool
|
||||
|
||||
config COMMON_CLK
|
||||
bool
|
||||
select HAVE_CLK_PREPARE
|
||||
@ -99,6 +96,14 @@ config COMMON_CLK_SI570
|
||||
This driver supports Silicon Labs 570/571/598/599 programmable
|
||||
clock generators.
|
||||
|
||||
config COMMON_CLK_CDCE706
|
||||
tristate "Clock driver for TI CDCE706 clock synthesizer"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
select RATIONAL
|
||||
---help---
|
||||
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
|
||||
|
||||
config COMMON_CLK_CDCE925
|
||||
tristate "Clock driver for TI CDCE925 devices"
|
||||
depends on I2C
|
||||
@ -190,15 +195,7 @@ config COMMON_CLK_PWM
|
||||
config COMMON_CLK_PXA
|
||||
def_bool COMMON_CLK && ARCH_PXA
|
||||
---help---
|
||||
Sypport for the Marvell PXA SoC.
|
||||
|
||||
config COMMON_CLK_CDCE706
|
||||
tristate "Clock driver for TI CDCE706 clock synthesizer"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
select RATIONAL
|
||||
---help---
|
||||
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
|
||||
Support for the Marvell PXA SoC.
|
||||
|
||||
source "drivers/clk/bcm/Kconfig"
|
||||
source "drivers/clk/hisilicon/Kconfig"
|
||||
@ -206,5 +203,6 @@ source "drivers/clk/mvebu/Kconfig"
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
source "drivers/clk/samsung/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -70,15 +70,14 @@ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
|
||||
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += shmobile/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += renesas/
|
||||
obj-$(CONFIG_ARCH_SIRF) += sirf/
|
||||
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
|
||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-$(CONFIG_ARCH_STI) += st/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
|
||||
obj-y += ti/
|
||||
obj-$(CONFIG_ARCH_U8500) += ux500/
|
||||
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
|
||||
obj-$(CONFIG_X86) += x86/
|
||||
|
@ -273,14 +273,14 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np)
|
||||
u32 id;
|
||||
const char *name;
|
||||
struct clk *clk;
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *parent_names[GENERATED_SOURCE_MAX];
|
||||
struct device_node *gcknp;
|
||||
struct clk_range range = CLK_RANGE(0, 0);
|
||||
struct regmap *regmap;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX)
|
||||
if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
|
@ -291,7 +291,7 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
|
||||
init.ops = &main_rc_osc_ops;
|
||||
init.parent_names = NULL;
|
||||
init.num_parents = 0;
|
||||
init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
|
||||
init.flags = CLK_IGNORE_UNUSED;
|
||||
|
||||
osc->hw.init = &init;
|
||||
osc->regmap = regmap;
|
||||
@ -572,12 +572,12 @@ static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk;
|
||||
const char *parent_names[2];
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *name = np->name;
|
||||
struct regmap *regmap;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > 2)
|
||||
if (num_parents == 0 || num_parents > 2)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
|
@ -199,14 +199,14 @@ of_at91_clk_master_setup(struct device_node *np,
|
||||
const struct clk_master_layout *layout)
|
||||
{
|
||||
struct clk *clk;
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *parent_names[MASTER_SOURCE_MAX];
|
||||
const char *name = np->name;
|
||||
struct clk_master_characteristics *characteristics;
|
||||
struct regmap *regmap;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
|
||||
if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
|
@ -230,14 +230,14 @@ of_at91_clk_prog_setup(struct device_node *np,
|
||||
int num;
|
||||
u32 id;
|
||||
struct clk *clk;
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *parent_names[PROG_SOURCE_MAX];
|
||||
const char *name;
|
||||
struct device_node *progclknp;
|
||||
struct regmap *regmap;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX)
|
||||
if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
|
@ -245,7 +245,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
|
||||
init.ops = &slow_rc_osc_ops;
|
||||
init.parent_names = NULL;
|
||||
init.num_parents = 0;
|
||||
init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
|
||||
init.flags = CLK_IGNORE_UNUSED;
|
||||
|
||||
osc->hw.init = &init;
|
||||
osc->sckcr = sckcr;
|
||||
@ -360,11 +360,11 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
|
||||
{
|
||||
struct clk *clk;
|
||||
const char *parent_names[2];
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *name = np->name;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > 2)
|
||||
if (num_parents == 0 || num_parents > 2)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
@ -433,7 +433,7 @@ static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk;
|
||||
const char *parent_names[2];
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *name = np->name;
|
||||
struct regmap *regmap;
|
||||
|
||||
|
@ -142,13 +142,13 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
|
||||
static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk;
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *parent_names[SMD_SOURCE_MAX];
|
||||
const char *name = np->name;
|
||||
struct regmap *regmap;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX)
|
||||
if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
|
@ -366,13 +366,13 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
|
||||
static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk;
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
const char *parent_names[USB_SOURCE_MAX];
|
||||
const char *name = np->name;
|
||||
struct regmap *regmap;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
|
||||
if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
|
||||
return;
|
||||
|
||||
of_clk_parent_fill(np, parent_names, num_parents);
|
||||
|
@ -38,8 +38,8 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev)
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(dev, res);
|
||||
if (!reg)
|
||||
return -ENODEV;
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
|
||||
if (!onecell)
|
||||
|
@ -88,10 +88,23 @@
|
||||
#define CM_HSMDIV 0x08c
|
||||
#define CM_OTPCTL 0x090
|
||||
#define CM_OTPDIV 0x094
|
||||
#define CM_PCMCTL 0x098
|
||||
#define CM_PCMDIV 0x09c
|
||||
#define CM_PWMCTL 0x0a0
|
||||
#define CM_PWMDIV 0x0a4
|
||||
#define CM_SLIMCTL 0x0a8
|
||||
#define CM_SLIMDIV 0x0ac
|
||||
#define CM_SMICTL 0x0b0
|
||||
#define CM_SMIDIV 0x0b4
|
||||
/* no definition for 0x0b8 and 0x0bc */
|
||||
#define CM_TCNTCTL 0x0c0
|
||||
#define CM_TCNTDIV 0x0c4
|
||||
#define CM_TECCTL 0x0c8
|
||||
#define CM_TECDIV 0x0cc
|
||||
#define CM_TD0CTL 0x0d0
|
||||
#define CM_TD0DIV 0x0d4
|
||||
#define CM_TD1CTL 0x0d8
|
||||
#define CM_TD1DIV 0x0dc
|
||||
#define CM_TSENSCTL 0x0e0
|
||||
#define CM_TSENSDIV 0x0e4
|
||||
#define CM_TIMERCTL 0x0e8
|
||||
@ -311,21 +324,18 @@ void __init bcm2835_init_clocks(void)
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
|
||||
126000000);
|
||||
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
|
||||
if (IS_ERR(clk))
|
||||
pr_err("apb_pclk not registered\n");
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
|
||||
3000000);
|
||||
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
|
||||
if (IS_ERR(clk))
|
||||
pr_err("uart0_pclk not registered\n");
|
||||
ret = clk_register_clkdev(clk, NULL, "20201000.uart");
|
||||
if (ret)
|
||||
pr_err("uart0_pclk alias not registered\n");
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
|
||||
125000000);
|
||||
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
|
||||
if (IS_ERR(clk))
|
||||
pr_err("uart1_pclk not registered\n");
|
||||
ret = clk_register_clkdev(clk, NULL, "20215000.uart");
|
||||
@ -1060,16 +1070,7 @@ static long bcm2835_pll_divider_round_rate(struct clk_hw *hw,
|
||||
static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
|
||||
struct bcm2835_cprman *cprman = divider->cprman;
|
||||
const struct bcm2835_pll_divider_data *data = divider->data;
|
||||
u32 div = cprman_read(cprman, data->a2w_reg);
|
||||
|
||||
div &= (1 << A2W_PLL_DIV_BITS) - 1;
|
||||
if (div == 0)
|
||||
div = 256;
|
||||
|
||||
return parent_rate / div;
|
||||
return clk_divider_ops.recalc_rate(hw, parent_rate);
|
||||
}
|
||||
|
||||
static void bcm2835_pll_divider_off(struct clk_hw *hw)
|
||||
@ -1107,13 +1108,15 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
|
||||
struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
|
||||
struct bcm2835_cprman *cprman = divider->cprman;
|
||||
const struct bcm2835_pll_divider_data *data = divider->data;
|
||||
u32 cm;
|
||||
int ret;
|
||||
u32 cm, div, max_div = 1 << A2W_PLL_DIV_BITS;
|
||||
|
||||
ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
div = DIV_ROUND_UP_ULL(parent_rate, rate);
|
||||
|
||||
div = min(div, max_div);
|
||||
if (div == max_div)
|
||||
div = 0;
|
||||
|
||||
cprman_write(cprman, data->a2w_reg, div);
|
||||
cm = cprman_read(cprman, data->cm_reg);
|
||||
cprman_write(cprman, data->cm_reg, cm | data->load_mask);
|
||||
cprman_write(cprman, data->cm_reg, cm & ~data->load_mask);
|
||||
@ -1428,7 +1431,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
|
||||
divider->div.reg = cprman->regs + data->a2w_reg;
|
||||
divider->div.shift = A2W_PLL_DIV_SHIFT;
|
||||
divider->div.width = A2W_PLL_DIV_BITS;
|
||||
divider->div.flags = 0;
|
||||
divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO;
|
||||
divider->div.lock = &cprman->regs_lock;
|
||||
divider->div.hw.init = &init;
|
||||
divider->div.table = NULL;
|
||||
|
@ -268,3 +268,62 @@ static void __init cygnus_asiu_init(struct device_node *node)
|
||||
iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div));
|
||||
}
|
||||
CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init);
|
||||
|
||||
/*
|
||||
* AUDIO PLL VCO frequency parameter table
|
||||
*
|
||||
* PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) *
|
||||
* (parent clock rate / pdiv)
|
||||
*
|
||||
* On Cygnus, parent is the 25MHz oscillator
|
||||
*/
|
||||
static const struct iproc_pll_vco_param audiopll_vco_params[] = {
|
||||
/* rate (Hz) ndiv_int ndiv_frac pdiv */
|
||||
{ 1354750204UL, 54, 199238, 1 },
|
||||
{ 1769470191UL, 70, 816639, 1 },
|
||||
};
|
||||
|
||||
static const struct iproc_pll_ctrl audiopll = {
|
||||
.flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC |
|
||||
IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW,
|
||||
.reset = RESET_VAL(0x5c, 0, 1),
|
||||
.dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3),
|
||||
.sw_ctrl = SW_CTRL_VAL(0x4, 0),
|
||||
.ndiv_int = REG_VAL(0x8, 0, 10),
|
||||
.ndiv_frac = REG_VAL(0x8, 10, 20),
|
||||
.pdiv = REG_VAL(0x44, 0, 4),
|
||||
.vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10),
|
||||
.status = REG_VAL(0x54, 0, 1),
|
||||
.macro_mode = REG_VAL(0x0, 0, 3),
|
||||
};
|
||||
|
||||
static const struct iproc_clk_ctrl audiopll_clk[] = {
|
||||
[BCM_CYGNUS_AUDIOPLL_CH0] = {
|
||||
.channel = BCM_CYGNUS_AUDIOPLL_CH0,
|
||||
.flags = IPROC_CLK_AON |
|
||||
IPROC_CLK_MCLK_DIV_BY_2,
|
||||
.enable = ENABLE_VAL(0x14, 8, 10, 9),
|
||||
.mdiv = REG_VAL(0x14, 0, 8),
|
||||
},
|
||||
[BCM_CYGNUS_AUDIOPLL_CH1] = {
|
||||
.channel = BCM_CYGNUS_AUDIOPLL_CH1,
|
||||
.flags = IPROC_CLK_AON,
|
||||
.enable = ENABLE_VAL(0x18, 8, 10, 9),
|
||||
.mdiv = REG_VAL(0x18, 0, 8),
|
||||
},
|
||||
[BCM_CYGNUS_AUDIOPLL_CH2] = {
|
||||
.channel = BCM_CYGNUS_AUDIOPLL_CH2,
|
||||
.flags = IPROC_CLK_AON,
|
||||
.enable = ENABLE_VAL(0x1c, 8, 10, 9),
|
||||
.mdiv = REG_VAL(0x1c, 0, 8),
|
||||
},
|
||||
};
|
||||
|
||||
static void __init cygnus_audiopll_clk_init(struct device_node *node)
|
||||
{
|
||||
iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params,
|
||||
ARRAY_SIZE(audiopll_vco_params), audiopll_clk,
|
||||
ARRAY_SIZE(audiopll_clk));
|
||||
}
|
||||
CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll",
|
||||
cygnus_audiopll_clk_init);
|
||||
|
@ -25,6 +25,12 @@
|
||||
#define PLL_VCO_HIGH_SHIFT 19
|
||||
#define PLL_VCO_LOW_SHIFT 30
|
||||
|
||||
/*
|
||||
* PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies
|
||||
* from a look-up table. Mode 7 allows user to manipulate PLL clock dividers
|
||||
*/
|
||||
#define PLL_USER_MODE 7
|
||||
|
||||
/* number of delay loops waiting for PLL to lock */
|
||||
#define LOCK_DELAY 100
|
||||
|
||||
@ -215,7 +221,10 @@ static void __pll_put_in_reset(struct iproc_pll *pll)
|
||||
const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
|
||||
|
||||
val = readl(pll->control_base + reset->offset);
|
||||
val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift);
|
||||
if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
|
||||
val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
|
||||
else
|
||||
val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
|
||||
iproc_pll_write(pll, pll->control_base, reset->offset, val);
|
||||
}
|
||||
|
||||
@ -236,7 +245,10 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
|
||||
iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
|
||||
|
||||
val = readl(pll->control_base + reset->offset);
|
||||
val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift;
|
||||
if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
|
||||
val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
|
||||
else
|
||||
val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
|
||||
iproc_pll_write(pll, pll->control_base, reset->offset, val);
|
||||
}
|
||||
|
||||
@ -292,6 +304,16 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
|
||||
/* put PLL in reset */
|
||||
__pll_put_in_reset(pll);
|
||||
|
||||
/* set PLL in user mode before modifying PLL controls */
|
||||
if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) {
|
||||
val = readl(pll->control_base + ctrl->macro_mode.offset);
|
||||
val &= ~(bit_mask(ctrl->macro_mode.width) <<
|
||||
ctrl->macro_mode.shift);
|
||||
val |= PLL_USER_MODE << ctrl->macro_mode.shift;
|
||||
iproc_pll_write(pll, pll->control_base,
|
||||
ctrl->macro_mode.offset, val);
|
||||
}
|
||||
|
||||
iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
|
||||
|
||||
val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
|
||||
@ -505,7 +527,10 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
|
||||
if (mdiv == 0)
|
||||
mdiv = 256;
|
||||
|
||||
clk->rate = parent_rate / mdiv;
|
||||
if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
|
||||
clk->rate = parent_rate / (mdiv * 2);
|
||||
else
|
||||
clk->rate = parent_rate / mdiv;
|
||||
|
||||
return clk->rate;
|
||||
}
|
||||
@ -543,7 +568,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
if (rate == 0 || parent_rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
div = DIV_ROUND_UP(parent_rate, rate);
|
||||
if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
|
||||
div = DIV_ROUND_UP(parent_rate, rate * 2);
|
||||
else
|
||||
div = DIV_ROUND_UP(parent_rate, rate);
|
||||
if (div > 256)
|
||||
return -EINVAL;
|
||||
|
||||
@ -555,7 +583,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
val |= div << ctrl->mdiv.shift;
|
||||
}
|
||||
iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
|
||||
clk->rate = parent_rate / div;
|
||||
if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
|
||||
clk->rate = parent_rate / (div * 2);
|
||||
else
|
||||
clk->rate = parent_rate / div;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -60,6 +60,26 @@
|
||||
*/
|
||||
#define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
|
||||
|
||||
/*
|
||||
* Some PLLs have an additional divide by 2 in master clock calculation;
|
||||
* MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know
|
||||
* of modified calculations
|
||||
*/
|
||||
#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)
|
||||
|
||||
/*
|
||||
* Some PLLs provide a look up table for the leaf clock frequencies and
|
||||
* auto calculates VCO frequency parameters based on the provided leaf
|
||||
* clock frequencies. They have a user mode that allows the divider
|
||||
* controls to be determined by the user
|
||||
*/
|
||||
#define IPROC_CLK_PLL_USER_MODE_ON BIT(8)
|
||||
|
||||
/*
|
||||
* Some PLLs have an active low reset
|
||||
*/
|
||||
#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)
|
||||
|
||||
/*
|
||||
* Parameters for VCO frequency configuration
|
||||
*
|
||||
@ -149,6 +169,7 @@ struct iproc_pll_ctrl {
|
||||
struct iproc_clk_reg_op pdiv;
|
||||
struct iproc_pll_vco_ctrl vco_ctrl;
|
||||
struct iproc_clk_reg_op status;
|
||||
struct iproc_clk_reg_op macro_mode;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -183,16 +204,16 @@ struct iproc_asiu_div {
|
||||
unsigned int low_width;
|
||||
};
|
||||
|
||||
void __init iproc_armpll_setup(struct device_node *node);
|
||||
void __init iproc_pll_clk_setup(struct device_node *node,
|
||||
const struct iproc_pll_ctrl *pll_ctrl,
|
||||
const struct iproc_pll_vco_param *vco,
|
||||
unsigned int num_vco_entries,
|
||||
const struct iproc_clk_ctrl *clk_ctrl,
|
||||
unsigned int num_clks);
|
||||
void __init iproc_asiu_setup(struct device_node *node,
|
||||
const struct iproc_asiu_div *div,
|
||||
const struct iproc_asiu_gate *gate,
|
||||
unsigned int num_clks);
|
||||
void iproc_armpll_setup(struct device_node *node);
|
||||
void iproc_pll_clk_setup(struct device_node *node,
|
||||
const struct iproc_pll_ctrl *pll_ctrl,
|
||||
const struct iproc_pll_vco_param *vco,
|
||||
unsigned int num_vco_entries,
|
||||
const struct iproc_clk_ctrl *clk_ctrl,
|
||||
unsigned int num_clks);
|
||||
void iproc_asiu_setup(struct device_node *node,
|
||||
const struct iproc_asiu_div *div,
|
||||
const struct iproc_asiu_gate *gate,
|
||||
unsigned int num_clks);
|
||||
|
||||
#endif /* _CLK_IPROC_H */
|
||||
|
@ -16,19 +16,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04
|
||||
#define AXI_CLKGEN_V1_REG_CLK_OUT1 0x08
|
||||
#define AXI_CLKGEN_V1_REG_CLK_OUT2 0x0c
|
||||
#define AXI_CLKGEN_V1_REG_CLK_DIV 0x10
|
||||
#define AXI_CLKGEN_V1_REG_CLK_FB1 0x14
|
||||
#define AXI_CLKGEN_V1_REG_CLK_FB2 0x18
|
||||
#define AXI_CLKGEN_V1_REG_LOCK1 0x1c
|
||||
#define AXI_CLKGEN_V1_REG_LOCK2 0x20
|
||||
#define AXI_CLKGEN_V1_REG_LOCK3 0x24
|
||||
#define AXI_CLKGEN_V1_REG_FILTER1 0x28
|
||||
#define AXI_CLKGEN_V1_REG_FILTER2 0x2c
|
||||
|
||||
#define AXI_CLKGEN_V2_REG_RESET 0x40
|
||||
#define AXI_CLKGEN_V2_REG_CLKSEL 0x44
|
||||
#define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70
|
||||
#define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74
|
||||
|
||||
@ -51,40 +40,11 @@
|
||||
#define MMCM_REG_FILTER1 0x4e
|
||||
#define MMCM_REG_FILTER2 0x4f
|
||||
|
||||
struct axi_clkgen;
|
||||
|
||||
struct axi_clkgen_mmcm_ops {
|
||||
void (*enable)(struct axi_clkgen *axi_clkgen, bool enable);
|
||||
int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg,
|
||||
unsigned int val, unsigned int mask);
|
||||
int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg,
|
||||
unsigned int *val);
|
||||
};
|
||||
|
||||
struct axi_clkgen {
|
||||
void __iomem *base;
|
||||
const struct axi_clkgen_mmcm_ops *mmcm_ops;
|
||||
struct clk_hw clk_hw;
|
||||
};
|
||||
|
||||
static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
|
||||
bool enable)
|
||||
{
|
||||
axi_clkgen->mmcm_ops->enable(axi_clkgen, enable);
|
||||
}
|
||||
|
||||
static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg, unsigned int val, unsigned int mask)
|
||||
{
|
||||
return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask);
|
||||
}
|
||||
|
||||
static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg, unsigned int *val)
|
||||
{
|
||||
return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val);
|
||||
}
|
||||
|
||||
static uint32_t axi_clkgen_lookup_filter(unsigned int m)
|
||||
{
|
||||
switch (m) {
|
||||
@ -207,70 +167,6 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
|
||||
*val = readl(axi_clkgen->base + reg);
|
||||
}
|
||||
|
||||
static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case MMCM_REG_CLKOUT0_1:
|
||||
return AXI_CLKGEN_V1_REG_CLK_OUT1;
|
||||
case MMCM_REG_CLKOUT0_2:
|
||||
return AXI_CLKGEN_V1_REG_CLK_OUT2;
|
||||
case MMCM_REG_CLK_FB1:
|
||||
return AXI_CLKGEN_V1_REG_CLK_FB1;
|
||||
case MMCM_REG_CLK_FB2:
|
||||
return AXI_CLKGEN_V1_REG_CLK_FB2;
|
||||
case MMCM_REG_CLK_DIV:
|
||||
return AXI_CLKGEN_V1_REG_CLK_DIV;
|
||||
case MMCM_REG_LOCK1:
|
||||
return AXI_CLKGEN_V1_REG_LOCK1;
|
||||
case MMCM_REG_LOCK2:
|
||||
return AXI_CLKGEN_V1_REG_LOCK2;
|
||||
case MMCM_REG_LOCK3:
|
||||
return AXI_CLKGEN_V1_REG_LOCK3;
|
||||
case MMCM_REG_FILTER1:
|
||||
return AXI_CLKGEN_V1_REG_FILTER1;
|
||||
case MMCM_REG_FILTER2:
|
||||
return AXI_CLKGEN_V1_REG_FILTER2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg, unsigned int val, unsigned int mask)
|
||||
{
|
||||
reg = axi_clkgen_v1_map_mmcm_reg(reg);
|
||||
if (reg == 0)
|
||||
return -EINVAL;
|
||||
|
||||
axi_clkgen_write(axi_clkgen, reg, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg, unsigned int *val)
|
||||
{
|
||||
reg = axi_clkgen_v1_map_mmcm_reg(reg);
|
||||
if (reg == 0)
|
||||
return -EINVAL;
|
||||
|
||||
axi_clkgen_read(axi_clkgen, reg, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen,
|
||||
bool enable)
|
||||
{
|
||||
axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable);
|
||||
}
|
||||
|
||||
static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = {
|
||||
.write = axi_clkgen_v1_mmcm_write,
|
||||
.read = axi_clkgen_v1_mmcm_read,
|
||||
.enable = axi_clkgen_v1_mmcm_enable,
|
||||
};
|
||||
|
||||
static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
|
||||
{
|
||||
unsigned int timeout = 10000;
|
||||
@ -286,7 +182,7 @@ static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
|
||||
return val & 0xffff;
|
||||
}
|
||||
|
||||
static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
|
||||
static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg, unsigned int *val)
|
||||
{
|
||||
unsigned int reg_val;
|
||||
@ -310,7 +206,7 @@ static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
|
||||
static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg, unsigned int val, unsigned int mask)
|
||||
{
|
||||
unsigned int reg_val = 0;
|
||||
@ -321,7 +217,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
|
||||
return ret;
|
||||
|
||||
if (mask != 0xffff) {
|
||||
axi_clkgen_v2_mmcm_read(axi_clkgen, reg, ®_val);
|
||||
axi_clkgen_mmcm_read(axi_clkgen, reg, ®_val);
|
||||
reg_val &= ~mask;
|
||||
}
|
||||
|
||||
@ -332,7 +228,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
|
||||
static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
|
||||
bool enable)
|
||||
{
|
||||
unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
|
||||
@ -343,12 +239,6 @@ static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
|
||||
axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
|
||||
}
|
||||
|
||||
static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = {
|
||||
.write = axi_clkgen_v2_mmcm_write,
|
||||
.read = axi_clkgen_v2_mmcm_read,
|
||||
.enable = axi_clkgen_v2_mmcm_enable,
|
||||
};
|
||||
|
||||
static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
|
||||
{
|
||||
return container_of(clk_hw, struct axi_clkgen, clk_hw);
|
||||
@ -438,10 +328,7 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
|
||||
tmp = (unsigned long long)(parent_rate / d) * m;
|
||||
do_div(tmp, dout);
|
||||
|
||||
if (tmp > ULONG_MAX)
|
||||
return ULONG_MAX;
|
||||
|
||||
return tmp;
|
||||
return min_t(unsigned long long, tmp, ULONG_MAX);
|
||||
}
|
||||
|
||||
static int axi_clkgen_enable(struct clk_hw *clk_hw)
|
||||
@ -460,21 +347,38 @@ static void axi_clkgen_disable(struct clk_hw *clk_hw)
|
||||
axi_clkgen_mmcm_enable(axi_clkgen, false);
|
||||
}
|
||||
|
||||
static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index)
|
||||
{
|
||||
struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
|
||||
|
||||
axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw)
|
||||
{
|
||||
struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
|
||||
unsigned int parent;
|
||||
|
||||
axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
static const struct clk_ops axi_clkgen_ops = {
|
||||
.recalc_rate = axi_clkgen_recalc_rate,
|
||||
.round_rate = axi_clkgen_round_rate,
|
||||
.set_rate = axi_clkgen_set_rate,
|
||||
.enable = axi_clkgen_enable,
|
||||
.disable = axi_clkgen_disable,
|
||||
.set_parent = axi_clkgen_set_parent,
|
||||
.get_parent = axi_clkgen_get_parent,
|
||||
};
|
||||
|
||||
static const struct of_device_id axi_clkgen_ids[] = {
|
||||
{
|
||||
.compatible = "adi,axi-clkgen-1.00.a",
|
||||
.data = &axi_clkgen_v1_mmcm_ops
|
||||
}, {
|
||||
.compatible = "adi,axi-clkgen-2.00.a",
|
||||
.data = &axi_clkgen_v2_mmcm_ops,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
@ -485,10 +389,11 @@ static int axi_clkgen_probe(struct platform_device *pdev)
|
||||
const struct of_device_id *id;
|
||||
struct axi_clkgen *axi_clkgen;
|
||||
struct clk_init_data init;
|
||||
const char *parent_name;
|
||||
const char *parent_names[2];
|
||||
const char *clk_name;
|
||||
struct resource *mem;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
if (!pdev->dev.of_node)
|
||||
return -ENODEV;
|
||||
@ -501,26 +406,29 @@ static int axi_clkgen_probe(struct platform_device *pdev)
|
||||
if (!axi_clkgen)
|
||||
return -ENOMEM;
|
||||
|
||||
axi_clkgen->mmcm_ops = id->data;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
if (IS_ERR(axi_clkgen->base))
|
||||
return PTR_ERR(axi_clkgen->base);
|
||||
|
||||
parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
|
||||
if (!parent_name)
|
||||
init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
|
||||
if (init.num_parents < 1 || init.num_parents > 2)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < init.num_parents; i++) {
|
||||
parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
|
||||
if (!parent_names[i])
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clk_name = pdev->dev.of_node->name;
|
||||
of_property_read_string(pdev->dev.of_node, "clock-output-names",
|
||||
&clk_name);
|
||||
|
||||
init.name = clk_name;
|
||||
init.ops = &axi_clkgen_ops;
|
||||
init.flags = CLK_SET_RATE_GATE;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
|
||||
init.parent_names = parent_names;
|
||||
|
||||
axi_clkgen_mmcm_enable(axi_clkgen, false);
|
||||
|
||||
|
@ -303,9 +303,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
|
||||
*/
|
||||
maxdiv = min(ULONG_MAX / rate, maxdiv);
|
||||
|
||||
for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) {
|
||||
if (!_is_valid_div(table, i, flags))
|
||||
continue;
|
||||
for (i = _next_div(table, 0, flags); i <= maxdiv;
|
||||
i = _next_div(table, i, flags)) {
|
||||
if (rate * i == parent_rate_saved) {
|
||||
/*
|
||||
* It's the most ideal case if the requested rate can be
|
||||
|
@ -36,7 +36,7 @@ static void __init efm32gg_cmu_init(struct device_node *np)
|
||||
}
|
||||
|
||||
clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL,
|
||||
CLK_IS_ROOT, 48000000);
|
||||
0, 48000000);
|
||||
|
||||
clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
|
||||
|
@ -100,6 +100,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
|
||||
|
||||
void clk_unregister_fixed_factor(struct clk *clk)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = __clk_get_hw(clk);
|
||||
if (!hw)
|
||||
return;
|
||||
|
||||
clk_unregister(clk);
|
||||
kfree(to_clk_fixed_factor(hw));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
|
||||
|
@ -104,6 +104,19 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
|
||||
|
||||
void clk_unregister_fixed_rate(struct clk *clk)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = __clk_get_hw(clk);
|
||||
if (!hw)
|
||||
return;
|
||||
|
||||
clk_unregister(clk);
|
||||
kfree(to_clk_fixed_rate(hw));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_fixed_clk_setup() - Setup function for simple fixed rate clock
|
||||
@ -123,8 +136,7 @@ void of_fixed_clk_setup(struct device_node *node)
|
||||
of_property_read_string(node, "clock-output-names", &clk_name);
|
||||
|
||||
clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
|
||||
CLK_IS_ROOT, rate,
|
||||
accuracy);
|
||||
0, rate, accuracy);
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
/**
|
||||
* DOC: basic gpio gated clock which can be enabled and disabled
|
||||
@ -199,134 +201,69 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* clk_register_get() has to be delayed, because -EPROBE_DEFER
|
||||
* can not be handled properly at of_clk_init() call time.
|
||||
*/
|
||||
|
||||
struct clk_gpio_delayed_register_data {
|
||||
const char *gpio_name;
|
||||
int num_parents;
|
||||
const char **parent_names;
|
||||
struct device_node *node;
|
||||
struct mutex lock;
|
||||
struct clk *clk;
|
||||
struct clk *(*clk_register_get)(const char *name,
|
||||
const char * const *parent_names, u8 num_parents,
|
||||
unsigned gpio, bool active_low);
|
||||
};
|
||||
|
||||
static struct clk *of_clk_gpio_delayed_register_get(
|
||||
struct of_phandle_args *clkspec, void *_data)
|
||||
static int gpio_clk_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_gpio_delayed_register_data *data = _data;
|
||||
struct clk *clk;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
const char **parent_names, *gpio_name;
|
||||
unsigned int num_parents;
|
||||
int gpio;
|
||||
enum of_gpio_flags of_flags;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
if (data->clk) {
|
||||
mutex_unlock(&data->lock);
|
||||
return data->clk;
|
||||
}
|
||||
|
||||
gpio = of_get_named_gpio_flags(data->node, data->gpio_name, 0,
|
||||
&of_flags);
|
||||
if (gpio < 0) {
|
||||
mutex_unlock(&data->lock);
|
||||
if (gpio == -EPROBE_DEFER)
|
||||
pr_debug("%s: %s: GPIOs not yet available, retry later\n",
|
||||
data->node->name, __func__);
|
||||
else
|
||||
pr_err("%s: %s: Can't get '%s' DT property\n",
|
||||
data->node->name, __func__,
|
||||
data->gpio_name);
|
||||
return ERR_PTR(gpio);
|
||||
}
|
||||
|
||||
clk = data->clk_register_get(data->node->name, data->parent_names,
|
||||
data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
|
||||
if (IS_ERR(clk))
|
||||
goto out;
|
||||
|
||||
data->clk = clk;
|
||||
out:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static struct clk *of_clk_gpio_gate_delayed_register_get(const char *name,
|
||||
const char * const *parent_names, u8 num_parents,
|
||||
unsigned gpio, bool active_low)
|
||||
{
|
||||
return clk_register_gpio_gate(NULL, name, parent_names ?
|
||||
parent_names[0] : NULL, gpio, active_low, 0);
|
||||
}
|
||||
|
||||
static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name,
|
||||
const char * const *parent_names, u8 num_parents, unsigned gpio,
|
||||
bool active_low)
|
||||
{
|
||||
return clk_register_gpio_mux(NULL, name, parent_names, num_parents,
|
||||
gpio, active_low, 0);
|
||||
}
|
||||
|
||||
static void __init of_gpio_clk_setup(struct device_node *node,
|
||||
const char *gpio_name,
|
||||
struct clk *(*clk_register_get)(const char *name,
|
||||
const char * const *parent_names,
|
||||
u8 num_parents,
|
||||
unsigned gpio, bool active_low))
|
||||
{
|
||||
struct clk_gpio_delayed_register_data *data;
|
||||
const char **parent_names;
|
||||
int i, num_parents;
|
||||
struct clk *clk;
|
||||
bool active_low, is_mux;
|
||||
|
||||
num_parents = of_clk_get_parent_count(node);
|
||||
if (num_parents < 0)
|
||||
num_parents = 0;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (num_parents) {
|
||||
parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
|
||||
if (!parent_names) {
|
||||
kfree(data);
|
||||
return;
|
||||
}
|
||||
parent_names = devm_kcalloc(&pdev->dev, num_parents,
|
||||
sizeof(char *), GFP_KERNEL);
|
||||
if (!parent_names)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
parent_names[i] = of_clk_get_parent_name(node, i);
|
||||
of_clk_parent_fill(node, parent_names, num_parents);
|
||||
} else {
|
||||
parent_names = NULL;
|
||||
}
|
||||
|
||||
data->num_parents = num_parents;
|
||||
data->parent_names = parent_names;
|
||||
data->node = node;
|
||||
data->gpio_name = gpio_name;
|
||||
data->clk_register_get = clk_register_get;
|
||||
mutex_init(&data->lock);
|
||||
is_mux = of_device_is_compatible(node, "gpio-mux-clock");
|
||||
|
||||
of_clk_add_provider(node, of_clk_gpio_delayed_register_get, data);
|
||||
gpio_name = is_mux ? "select-gpios" : "enable-gpios";
|
||||
gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags);
|
||||
if (gpio < 0) {
|
||||
if (gpio == -EPROBE_DEFER)
|
||||
pr_debug("%s: %s: GPIOs not yet available, retry later\n",
|
||||
node->name, __func__);
|
||||
else
|
||||
pr_err("%s: %s: Can't get '%s' DT property\n",
|
||||
node->name, __func__,
|
||||
gpio_name);
|
||||
return gpio;
|
||||
}
|
||||
|
||||
active_low = of_flags & OF_GPIO_ACTIVE_LOW;
|
||||
|
||||
if (is_mux)
|
||||
clk = clk_register_gpio_mux(&pdev->dev, node->name,
|
||||
parent_names, num_parents, gpio, active_low, 0);
|
||||
else
|
||||
clk = clk_register_gpio_gate(&pdev->dev, node->name,
|
||||
parent_names ? parent_names[0] : NULL, gpio,
|
||||
active_low, 0);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
return of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
}
|
||||
|
||||
static void __init of_gpio_gate_clk_setup(struct device_node *node)
|
||||
{
|
||||
of_gpio_clk_setup(node, "enable-gpios",
|
||||
of_clk_gpio_gate_delayed_register_get);
|
||||
}
|
||||
CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup);
|
||||
static const struct of_device_id gpio_clk_match_table[] = {
|
||||
{ .compatible = "gpio-mux-clock" },
|
||||
{ .compatible = "gpio-gate-clock" },
|
||||
{ }
|
||||
};
|
||||
|
||||
void __init of_gpio_mux_clk_setup(struct device_node *node)
|
||||
{
|
||||
of_gpio_clk_setup(node, "select-gpios",
|
||||
of_clk_gpio_mux_delayed_register_get);
|
||||
}
|
||||
CLK_OF_DECLARE(gpio_mux_clk, "gpio-mux-clock", of_gpio_mux_clk_setup);
|
||||
#endif
|
||||
static struct platform_driver gpio_clk_driver = {
|
||||
.probe = gpio_clk_driver_probe,
|
||||
.driver = {
|
||||
.name = "gpio-clk",
|
||||
.of_match_table = gpio_clk_match_table,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(gpio_clk_driver);
|
||||
|
@ -38,17 +38,14 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
|
||||
[MAX77686_CLK_AP] = {
|
||||
.name = "32khz_ap",
|
||||
.ops = &max_gen_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[MAX77686_CLK_CP] = {
|
||||
.name = "32khz_cp",
|
||||
.ops = &max_gen_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[MAX77686_CLK_PMIC] = {
|
||||
.name = "32khz_pmic",
|
||||
.ops = &max_gen_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -39,12 +39,10 @@ static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = {
|
||||
[MAX77802_CLK_32K_AP] = {
|
||||
.name = "32khz_ap",
|
||||
.ops = &max_gen_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[MAX77802_CLK_32K_CP] = {
|
||||
.name = "32khz_cp",
|
||||
.ops = &max_gen_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -217,7 +217,7 @@ static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data)
|
||||
init.name = clkp;
|
||||
init.num_parents = 0;
|
||||
init.ops = &crg_port_ops;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
init.flags = 0;
|
||||
crgclk->hw.init = &init;
|
||||
crgclk->cntrlr = cntrlr;
|
||||
crgclk->domain = domain;
|
||||
@ -341,7 +341,7 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
|
||||
|
||||
init.name = dev_name(cpu_dev);
|
||||
init.ops = &clk_clc_ops;
|
||||
init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
|
||||
init.flags = CLK_GET_RATE_NOCACHE;
|
||||
init.num_parents = 0;
|
||||
|
||||
return devm_clk_register(cpu_dev, &clc->hw);
|
||||
|
@ -44,7 +44,7 @@ struct palmas_clock_info {
|
||||
struct clk *clk;
|
||||
struct clk_hw hw;
|
||||
struct palmas *palmas;
|
||||
struct palmas_clk32k_desc *clk_desc;
|
||||
const struct palmas_clk32k_desc *clk_desc;
|
||||
int ext_control_pin;
|
||||
};
|
||||
|
||||
@ -125,10 +125,10 @@ static struct clk_ops palmas_clks_ops = {
|
||||
|
||||
struct palmas_clks_of_match_data {
|
||||
struct clk_init_data init;
|
||||
struct palmas_clk32k_desc desc;
|
||||
const struct palmas_clk32k_desc desc;
|
||||
};
|
||||
|
||||
static struct palmas_clks_of_match_data palmas_of_clk32kg = {
|
||||
static const struct palmas_clks_of_match_data palmas_of_clk32kg = {
|
||||
.init = {
|
||||
.name = "clk32kg",
|
||||
.ops = &palmas_clks_ops,
|
||||
@ -144,7 +144,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kg = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
|
||||
static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
|
||||
.init = {
|
||||
.name = "clk32kgaudio",
|
||||
.ops = &palmas_clks_ops,
|
||||
@ -240,14 +240,14 @@ static int palmas_clks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct palmas_clks_of_match_data *match_data;
|
||||
const struct of_device_id *match;
|
||||
const struct palmas_clks_of_match_data *match_data;
|
||||
struct palmas_clock_info *cinfo;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
match = of_match_device(palmas_clks_of_match, &pdev->dev);
|
||||
match_data = (struct palmas_clks_of_match_data *)match->data;
|
||||
match_data = of_device_get_match_data(&pdev->dev);
|
||||
if (!match_data)
|
||||
return 1;
|
||||
|
||||
cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL);
|
||||
if (!cinfo)
|
||||
|
@ -95,7 +95,7 @@ static int clk_pwm_probe(struct platform_device *pdev)
|
||||
|
||||
init.name = clk_name;
|
||||
init.ops = &clk_pwm_ops;
|
||||
init.flags = CLK_IS_BASIC | CLK_IS_ROOT;
|
||||
init.flags = CLK_IS_BASIC;
|
||||
init.num_parents = 0;
|
||||
|
||||
clk_pwm->pwm = pwm;
|
||||
|
@ -99,17 +99,14 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = {
|
||||
[S2MPS11_CLK_AP] = {
|
||||
.name = "s2mps11_ap",
|
||||
.ops = &s2mps11_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[S2MPS11_CLK_CP] = {
|
||||
.name = "s2mps11_cp",
|
||||
.ops = &s2mps11_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[S2MPS11_CLK_BT] = {
|
||||
.name = "s2mps11_bt",
|
||||
.ops = &s2mps11_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -155,7 +155,7 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
|
||||
unsigned long min = 0, max = 0;
|
||||
|
||||
init.name = name;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
init.flags = 0;
|
||||
init.num_parents = 0;
|
||||
init.ops = match->data;
|
||||
sclk->hw.init = &init;
|
||||
|
@ -313,7 +313,7 @@ static int si514_probe(struct i2c_client *client,
|
||||
return -ENOMEM;
|
||||
|
||||
init.ops = &si514_clk_ops;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
init.flags = 0;
|
||||
init.num_parents = 0;
|
||||
data->hw.init = &init;
|
||||
data->i2c_client = client;
|
||||
|
@ -1495,7 +1495,7 @@ static int si5351_i2c_probe(struct i2c_client *client,
|
||||
if (drvdata->variant == SI5351_VARIANT_B) {
|
||||
init.name = si5351_pll_names[2];
|
||||
init.ops = &si5351_vxco_ops;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
init.flags = 0;
|
||||
init.parent_names = NULL;
|
||||
init.num_parents = 0;
|
||||
} else {
|
||||
|
@ -418,7 +418,7 @@ static int si570_probe(struct i2c_client *client,
|
||||
return -ENOMEM;
|
||||
|
||||
init.ops = &si570_clk_ops;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
init.flags = 0;
|
||||
init.num_parents = 0;
|
||||
data->hw.init = &init;
|
||||
data->i2c_client = client;
|
||||
|
@ -355,7 +355,7 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
|
||||
#define WM8850_BITS_TO_VAL(m, d1, d2) \
|
||||
((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2)
|
||||
|
||||
static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
u32 *multiplier, u32 *prediv)
|
||||
{
|
||||
unsigned long tclk;
|
||||
@ -365,7 +365,7 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
pr_err("%s: requested rate out of range\n", __func__);
|
||||
*multiplier = 0;
|
||||
*prediv = 1;
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (rate <= parent_rate * 31)
|
||||
/* use the prediv to double the resolution */
|
||||
@ -379,12 +379,15 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
if (tclk != rate)
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__,
|
||||
rate, tclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
u32 *multiplier, u32 *divisor1, u32 *divisor2)
|
||||
{
|
||||
u32 mul, div1, div2;
|
||||
u32 mul, div1;
|
||||
int div2;
|
||||
u32 best_mul, best_div1, best_div2;
|
||||
unsigned long tclk, rate_err, best_err;
|
||||
|
||||
@ -403,7 +406,7 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
*multiplier = mul;
|
||||
*divisor1 = div1;
|
||||
*divisor2 = div2;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rate_err < best_err) {
|
||||
@ -414,12 +417,19 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
}
|
||||
}
|
||||
|
||||
if (best_err == (unsigned long)-1) {
|
||||
pr_warn("%s: impossible rate %lu\n", __func__, rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* if we got here, it wasn't an exact match */
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
|
||||
rate - best_err);
|
||||
*multiplier = best_mul;
|
||||
*divisor1 = best_div1;
|
||||
*divisor2 = best_div2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1)
|
||||
@ -449,10 +459,11 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2)
|
||||
{
|
||||
u32 mul, div1, div2;
|
||||
u32 mul;
|
||||
int div1, div2;
|
||||
u32 best_mul, best_div1, best_div2;
|
||||
unsigned long tclk, rate_err, best_err;
|
||||
|
||||
@ -472,7 +483,7 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
*multiplier = mul;
|
||||
*divisor1 = div1;
|
||||
*divisor2 = div2;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rate_err < best_err) {
|
||||
@ -483,6 +494,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
}
|
||||
}
|
||||
|
||||
if (best_err == (unsigned long)-1) {
|
||||
pr_warn("%s: impossible rate %lu\n", __func__, rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* if we got here, it wasn't an exact match */
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
|
||||
rate - best_err);
|
||||
@ -491,12 +507,15 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
*multiplier = best_mul;
|
||||
*divisor1 = best_div1;
|
||||
*divisor2 = best_div2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
u32 *multiplier, u32 *divisor1, u32 *divisor2)
|
||||
{
|
||||
u32 mul, div1, div2;
|
||||
u32 mul;
|
||||
int div1, div2;
|
||||
u32 best_mul, best_div1, best_div2;
|
||||
unsigned long tclk, rate_err, best_err;
|
||||
|
||||
@ -516,7 +535,7 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
*multiplier = mul;
|
||||
*divisor1 = div1;
|
||||
*divisor2 = div2;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rate_err < best_err) {
|
||||
@ -527,6 +546,11 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
}
|
||||
}
|
||||
|
||||
if (best_err == (unsigned long)-1) {
|
||||
pr_warn("%s: impossible rate %lu\n", __func__, rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* if we got here, it wasn't an exact match */
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
|
||||
rate - best_err);
|
||||
@ -534,6 +558,8 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
*multiplier = best_mul;
|
||||
*divisor1 = best_div1;
|
||||
*divisor2 = best_div2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
@ -543,31 +569,39 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
u32 filter, mul, div1, div2;
|
||||
u32 pll_val;
|
||||
unsigned long flags = 0;
|
||||
int ret;
|
||||
|
||||
/* sanity check */
|
||||
|
||||
switch (pll->type) {
|
||||
case PLL_TYPE_VT8500:
|
||||
vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
|
||||
pll_val = VT8500_BITS_TO_VAL(mul, div1);
|
||||
ret = vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
|
||||
if (!ret)
|
||||
pll_val = VT8500_BITS_TO_VAL(mul, div1);
|
||||
break;
|
||||
case PLL_TYPE_WM8650:
|
||||
wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
|
||||
pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
|
||||
ret = wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
|
||||
if (!ret)
|
||||
pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
|
||||
break;
|
||||
case PLL_TYPE_WM8750:
|
||||
wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
|
||||
pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
|
||||
ret = wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
|
||||
if (!ret)
|
||||
pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
|
||||
break;
|
||||
case PLL_TYPE_WM8850:
|
||||
wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
|
||||
pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
|
||||
ret = wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
|
||||
if (!ret)
|
||||
pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid pll type\n", __func__);
|
||||
return 0;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(pll->lock, flags);
|
||||
|
||||
vt8500_pmc_wait_busy();
|
||||
@ -585,28 +619,36 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
u32 filter, mul, div1, div2;
|
||||
long round_rate;
|
||||
int ret;
|
||||
|
||||
switch (pll->type) {
|
||||
case PLL_TYPE_VT8500:
|
||||
vt8500_find_pll_bits(rate, *prate, &mul, &div1);
|
||||
round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
|
||||
ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1);
|
||||
if (!ret)
|
||||
round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1);
|
||||
break;
|
||||
case PLL_TYPE_WM8650:
|
||||
wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
|
||||
round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
|
||||
ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
|
||||
if (!ret)
|
||||
round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2);
|
||||
break;
|
||||
case PLL_TYPE_WM8750:
|
||||
wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
|
||||
round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
|
||||
ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
|
||||
if (!ret)
|
||||
round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
|
||||
break;
|
||||
case PLL_TYPE_WM8850:
|
||||
wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
|
||||
round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
|
||||
ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
|
||||
if (!ret)
|
||||
round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
|
||||
break;
|
||||
default:
|
||||
round_rate = 0;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return round_rate;
|
||||
}
|
||||
|
||||
|
@ -376,8 +376,8 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
/* Set new divider */
|
||||
data = xgene_clk_read(pclk->param.divider_reg +
|
||||
pclk->param.reg_divider_offset);
|
||||
data &= ~((1 << pclk->param.reg_divider_width) - 1)
|
||||
<< pclk->param.reg_divider_shift;
|
||||
data &= ~(((1 << pclk->param.reg_divider_width) - 1)
|
||||
<< pclk->param.reg_divider_shift);
|
||||
data |= divider;
|
||||
xgene_clk_write(data, pclk->param.divider_reg +
|
||||
pclk->param.reg_divider_offset);
|
||||
|
@ -350,13 +350,12 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
|
||||
{
|
||||
if (!core || index >= core->num_parents)
|
||||
return NULL;
|
||||
else if (!core->parents)
|
||||
return clk_core_lookup(core->parent_names[index]);
|
||||
else if (!core->parents[index])
|
||||
return core->parents[index] =
|
||||
clk_core_lookup(core->parent_names[index]);
|
||||
else
|
||||
return core->parents[index];
|
||||
|
||||
if (!core->parents[index])
|
||||
core->parents[index] =
|
||||
clk_core_lookup(core->parent_names[index]);
|
||||
|
||||
return core->parents[index];
|
||||
}
|
||||
|
||||
struct clk_hw *
|
||||
@ -386,7 +385,7 @@ static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
|
||||
|
||||
ret = core->rate;
|
||||
|
||||
if (core->flags & CLK_IS_ROOT)
|
||||
if (!core->num_parents)
|
||||
goto out;
|
||||
|
||||
if (!core->parent)
|
||||
@ -1067,31 +1066,13 @@ static int clk_fetch_parent_index(struct clk_core *core,
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!core->parents) {
|
||||
core->parents = kcalloc(core->num_parents,
|
||||
sizeof(struct clk *), GFP_KERNEL);
|
||||
if (!core->parents)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* find index of new parent clock using cached parent ptrs,
|
||||
* or if not yet cached, use string name comparison and cache
|
||||
* them now to avoid future calls to clk_core_lookup.
|
||||
*/
|
||||
for (i = 0; i < core->num_parents; i++) {
|
||||
if (core->parents[i] == parent)
|
||||
for (i = 0; i < core->num_parents; i++)
|
||||
if (clk_core_get_parent_by_index(core, i) == parent)
|
||||
return i;
|
||||
|
||||
if (core->parents[i])
|
||||
continue;
|
||||
|
||||
if (!strcmp(core->parent_names[i], parent->name)) {
|
||||
core->parents[i] = clk_core_lookup(parent->name);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1677,56 +1658,14 @@ struct clk *clk_get_parent(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_get_parent);
|
||||
|
||||
/*
|
||||
* .get_parent is mandatory for clocks with multiple possible parents. It is
|
||||
* optional for single-parent clocks. Always call .get_parent if it is
|
||||
* available and WARN if it is missing for multi-parent clocks.
|
||||
*
|
||||
* For single-parent clocks without .get_parent, first check to see if the
|
||||
* .parents array exists, and if so use it to avoid an expensive tree
|
||||
* traversal. If .parents does not exist then walk the tree.
|
||||
*/
|
||||
static struct clk_core *__clk_init_parent(struct clk_core *core)
|
||||
{
|
||||
struct clk_core *ret = NULL;
|
||||
u8 index;
|
||||
u8 index = 0;
|
||||
|
||||
/* handle the trivial cases */
|
||||
if (core->num_parents > 1 && core->ops->get_parent)
|
||||
index = core->ops->get_parent(core->hw);
|
||||
|
||||
if (!core->num_parents)
|
||||
goto out;
|
||||
|
||||
if (core->num_parents == 1) {
|
||||
if (IS_ERR_OR_NULL(core->parent))
|
||||
core->parent = clk_core_lookup(core->parent_names[0]);
|
||||
ret = core->parent;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!core->ops->get_parent) {
|
||||
WARN(!core->ops->get_parent,
|
||||
"%s: multi-parent clocks must implement .get_parent\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do our best to cache parent clocks in core->parents. This prevents
|
||||
* unnecessary and expensive lookups. We don't set core->parent here;
|
||||
* that is done by the calling function.
|
||||
*/
|
||||
|
||||
index = core->ops->get_parent(core->hw);
|
||||
|
||||
if (!core->parents)
|
||||
core->parents =
|
||||
kcalloc(core->num_parents, sizeof(struct clk *),
|
||||
GFP_KERNEL);
|
||||
|
||||
ret = clk_core_get_parent_by_index(core, index);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
return clk_core_get_parent_by_index(core, index);
|
||||
}
|
||||
|
||||
static void clk_core_reparent(struct clk_core *core,
|
||||
@ -1809,13 +1748,13 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
|
||||
/* try finding the new parent index */
|
||||
if (parent) {
|
||||
p_index = clk_fetch_parent_index(core, parent);
|
||||
p_rate = parent->rate;
|
||||
if (p_index < 0) {
|
||||
pr_debug("%s: clk %s can not be parent of clk %s\n",
|
||||
__func__, parent->name, core->name);
|
||||
ret = p_index;
|
||||
goto out;
|
||||
}
|
||||
p_rate = parent->rate;
|
||||
}
|
||||
|
||||
/* propagate PRE_RATE_CHANGE notifications */
|
||||
@ -1902,6 +1841,10 @@ int clk_set_phase(struct clk *clk, int degrees)
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
/* bail early if nothing to do */
|
||||
if (degrees == clk->core->phase)
|
||||
goto out;
|
||||
|
||||
trace_clk_set_phase(clk->core, degrees);
|
||||
|
||||
if (clk->core->ops->set_phase)
|
||||
@ -1912,6 +1855,7 @@ int clk_set_phase(struct clk *clk, int degrees)
|
||||
if (!ret)
|
||||
clk->core->phase = degrees;
|
||||
|
||||
out:
|
||||
clk_prepare_unlock();
|
||||
|
||||
return ret;
|
||||
@ -2218,7 +2162,7 @@ unlock:
|
||||
*
|
||||
* Dynamically removes a clk and all its child nodes from the
|
||||
* debugfs clk directory if clk->dentry points to debugfs created by
|
||||
* clk_debug_register in __clk_init.
|
||||
* clk_debug_register in __clk_core_init.
|
||||
*/
|
||||
static void clk_debug_unregister(struct clk_core *core)
|
||||
{
|
||||
@ -2303,26 +2247,22 @@ static inline void clk_debug_unregister(struct clk_core *core)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __clk_init - initialize the data structures in a struct clk
|
||||
* @dev: device initializing this clk, placeholder for now
|
||||
* @clk: clk being initialized
|
||||
* __clk_core_init - initialize the data structures in a struct clk_core
|
||||
* @core: clk_core being initialized
|
||||
*
|
||||
* Initializes the lists in struct clk_core, queries the hardware for the
|
||||
* parent and rate and sets them both.
|
||||
*/
|
||||
static int __clk_init(struct device *dev, struct clk *clk_user)
|
||||
static int __clk_core_init(struct clk_core *core)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct clk_core *orphan;
|
||||
struct hlist_node *tmp2;
|
||||
struct clk_core *core;
|
||||
unsigned long rate;
|
||||
|
||||
if (!clk_user)
|
||||
if (!core)
|
||||
return -EINVAL;
|
||||
|
||||
core = clk_user->core;
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
/* check to see if a clock with this name is already registered */
|
||||
@ -2337,22 +2277,29 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
|
||||
if (core->ops->set_rate &&
|
||||
!((core->ops->round_rate || core->ops->determine_rate) &&
|
||||
core->ops->recalc_rate)) {
|
||||
pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
|
||||
__func__, core->name);
|
||||
pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
|
||||
__func__, core->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (core->ops->set_parent && !core->ops->get_parent) {
|
||||
pr_warning("%s: %s must implement .get_parent & .set_parent\n",
|
||||
__func__, core->name);
|
||||
pr_err("%s: %s must implement .get_parent & .set_parent\n",
|
||||
__func__, core->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (core->num_parents > 1 && !core->ops->get_parent) {
|
||||
pr_err("%s: %s must implement .get_parent as it has multi parents\n",
|
||||
__func__, core->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (core->ops->set_rate_and_parent &&
|
||||
!(core->ops->set_parent && core->ops->set_rate)) {
|
||||
pr_warn("%s: %s must implement .set_parent & .set_rate\n",
|
||||
pr_err("%s: %s must implement .set_parent & .set_rate\n",
|
||||
__func__, core->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
@ -2364,37 +2311,12 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
|
||||
"%s: invalid NULL in %s's .parent_names\n",
|
||||
__func__, core->name);
|
||||
|
||||
/*
|
||||
* Allocate an array of struct clk *'s to avoid unnecessary string
|
||||
* look-ups of clk's possible parents. This can fail for clocks passed
|
||||
* in to clk_init during early boot; thus any access to core->parents[]
|
||||
* must always check for a NULL pointer and try to populate it if
|
||||
* necessary.
|
||||
*
|
||||
* If core->parents is not NULL we skip this entire block. This allows
|
||||
* for clock drivers to statically initialize core->parents.
|
||||
*/
|
||||
if (core->num_parents > 1 && !core->parents) {
|
||||
core->parents = kcalloc(core->num_parents, sizeof(struct clk *),
|
||||
GFP_KERNEL);
|
||||
/*
|
||||
* clk_core_lookup returns NULL for parents that have not been
|
||||
* clk_init'd; thus any access to clk->parents[] must check
|
||||
* for a NULL pointer. We can always perform lazy lookups for
|
||||
* missing parents later on.
|
||||
*/
|
||||
if (core->parents)
|
||||
for (i = 0; i < core->num_parents; i++)
|
||||
core->parents[i] =
|
||||
clk_core_lookup(core->parent_names[i]);
|
||||
}
|
||||
|
||||
core->parent = __clk_init_parent(core);
|
||||
|
||||
/*
|
||||
* Populate core->parent if parent has already been __clk_init'd. If
|
||||
* parent has not yet been __clk_init'd then place clk in the orphan
|
||||
* list. If clk has set the CLK_IS_ROOT flag then place it in the root
|
||||
* Populate core->parent if parent has already been clk_core_init'd. If
|
||||
* parent has not yet been clk_core_init'd then place clk in the orphan
|
||||
* list. If clk doesn't have any parents then place it in the root
|
||||
* clk list.
|
||||
*
|
||||
* Every time a new clk is clk_init'd then we walk the list of orphan
|
||||
@ -2405,7 +2327,7 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
|
||||
hlist_add_head(&core->child_node,
|
||||
&core->parent->children);
|
||||
core->orphan = core->parent->orphan;
|
||||
} else if (core->flags & CLK_IS_ROOT) {
|
||||
} else if (!core->num_parents) {
|
||||
hlist_add_head(&core->child_node, &clk_root_list);
|
||||
core->orphan = false;
|
||||
} else {
|
||||
@ -2454,24 +2376,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
|
||||
core->rate = core->req_rate = rate;
|
||||
|
||||
/*
|
||||
* walk the list of orphan clocks and reparent any that are children of
|
||||
* this clock
|
||||
* walk the list of orphan clocks and reparent any that newly finds a
|
||||
* parent.
|
||||
*/
|
||||
hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
|
||||
if (orphan->num_parents && orphan->ops->get_parent) {
|
||||
i = orphan->ops->get_parent(orphan->hw);
|
||||
if (i >= 0 && i < orphan->num_parents &&
|
||||
!strcmp(core->name, orphan->parent_names[i]))
|
||||
clk_core_reparent(orphan, core);
|
||||
continue;
|
||||
}
|
||||
struct clk_core *parent = __clk_init_parent(orphan);
|
||||
|
||||
for (i = 0; i < orphan->num_parents; i++)
|
||||
if (!strcmp(core->name, orphan->parent_names[i])) {
|
||||
clk_core_reparent(orphan, core);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (parent)
|
||||
clk_core_reparent(orphan, parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* optional platform-specific magic
|
||||
@ -2585,21 +2498,31 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
/* avoid unnecessary string look-ups of clk_core's possible parents. */
|
||||
core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
|
||||
GFP_KERNEL);
|
||||
if (!core->parents) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_parents;
|
||||
};
|
||||
|
||||
INIT_HLIST_HEAD(&core->clks);
|
||||
|
||||
hw->clk = __clk_create_clk(hw, NULL, NULL);
|
||||
if (IS_ERR(hw->clk)) {
|
||||
ret = PTR_ERR(hw->clk);
|
||||
goto fail_parent_names_copy;
|
||||
goto fail_parents;
|
||||
}
|
||||
|
||||
ret = __clk_init(dev, hw->clk);
|
||||
ret = __clk_core_init(core);
|
||||
if (!ret)
|
||||
return hw->clk;
|
||||
|
||||
__clk_free_clk(hw->clk);
|
||||
hw->clk = NULL;
|
||||
|
||||
fail_parents:
|
||||
kfree(core->parents);
|
||||
fail_parent_names_copy:
|
||||
while (--i >= 0)
|
||||
kfree_const(core->parent_names[i]);
|
||||
@ -2683,7 +2606,7 @@ void clk_unregister(struct clk *clk)
|
||||
if (clk->core->ops == &clk_nodrv_ops) {
|
||||
pr_err("%s: unregistered clock: %s\n", __func__,
|
||||
clk->core->name);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
/*
|
||||
* Assign empty clock ops for consumers that might still hold
|
||||
@ -2709,7 +2632,7 @@ void clk_unregister(struct clk *clk)
|
||||
pr_warn("%s: unregistering prepared clock: %s\n",
|
||||
__func__, clk->core->name);
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
|
||||
unlock:
|
||||
clk_prepare_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unregister);
|
||||
@ -3061,10 +2984,23 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
|
||||
{
|
||||
return __of_clk_get_from_provider(clkspec, NULL, __func__);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
|
||||
|
||||
int of_clk_get_parent_count(struct device_node *np)
|
||||
/**
|
||||
* of_clk_get_parent_count() - Count the number of clocks a device node has
|
||||
* @np: device node to count
|
||||
*
|
||||
* Returns: The number of clocks that are possible parents of this node
|
||||
*/
|
||||
unsigned int of_clk_get_parent_count(struct device_node *np)
|
||||
{
|
||||
return of_count_phandle_with_args(np, "clocks", "#clock-cells");
|
||||
int count;
|
||||
|
||||
count = of_count_phandle_with_args(np, "clocks", "#clock-cells");
|
||||
if (count < 0)
|
||||
return 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
|
||||
|
||||
@ -3214,6 +3150,9 @@ void __init of_clk_init(const struct of_device_id *matches)
|
||||
for_each_matching_node_and_match(np, matches, &match) {
|
||||
struct clock_provider *parent;
|
||||
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
|
||||
parent = kzalloc(sizeof(*parent), GFP_KERNEL);
|
||||
if (!parent) {
|
||||
list_for_each_entry_safe(clk_provider, next,
|
||||
|
@ -13,7 +13,7 @@ static DEFINE_SPINLOCK(clklock);
|
||||
|
||||
static void __init h8300_div_clk_setup(struct device_node *node)
|
||||
{
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
struct clk *clk;
|
||||
const char *clk_name = node->name;
|
||||
const char *parent_name;
|
||||
@ -22,7 +22,7 @@ static void __init h8300_div_clk_setup(struct device_node *node)
|
||||
int offset;
|
||||
|
||||
num_parents = of_clk_get_parent_count(node);
|
||||
if (num_parents < 1) {
|
||||
if (!num_parents) {
|
||||
pr_err("%s: no parent found", clk_name);
|
||||
return;
|
||||
}
|
||||
@ -34,7 +34,7 @@ static void __init h8300_div_clk_setup(struct device_node *node)
|
||||
}
|
||||
offset = (unsigned long)divcr & 3;
|
||||
offset = (3 - offset) * 8;
|
||||
divcr = (void *)((unsigned long)divcr & ~3);
|
||||
divcr = (void __iomem *)((unsigned long)divcr & ~3);
|
||||
|
||||
parent_name = of_clk_get_parent_name(node, 0);
|
||||
of_property_read_u32(node, "renesas,width", &width);
|
||||
|
@ -83,7 +83,7 @@ static const struct clk_ops pll_ops = {
|
||||
|
||||
static void __init h8s2678_pll_clk_setup(struct device_node *node)
|
||||
{
|
||||
int num_parents;
|
||||
unsigned int num_parents;
|
||||
struct clk *clk;
|
||||
const char *clk_name = node->name;
|
||||
const char *parent_name;
|
||||
@ -91,7 +91,7 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node)
|
||||
struct clk_init_data init;
|
||||
|
||||
num_parents = of_clk_get_parent_count(node);
|
||||
if (num_parents < 1) {
|
||||
if (!num_parents) {
|
||||
pr_err("%s: no parent found", clk_name);
|
||||
return;
|
||||
}
|
||||
|
@ -78,15 +78,15 @@ static const char *const mmc3_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
|
||||
/* fixed rate clocks */
|
||||
static struct hisi_fixed_rate_clock hi3620_fixed_rate_clks[] __initdata = {
|
||||
{ HI3620_OSC32K, "osc32k", NULL, CLK_IS_ROOT, 32768, },
|
||||
{ HI3620_OSC26M, "osc26m", NULL, CLK_IS_ROOT, 26000000, },
|
||||
{ HI3620_PCLK, "pclk", NULL, CLK_IS_ROOT, 26000000, },
|
||||
{ HI3620_PLL_ARM0, "armpll0", NULL, CLK_IS_ROOT, 1600000000, },
|
||||
{ HI3620_PLL_ARM1, "armpll1", NULL, CLK_IS_ROOT, 1600000000, },
|
||||
{ HI3620_PLL_PERI, "armpll2", NULL, CLK_IS_ROOT, 1440000000, },
|
||||
{ HI3620_PLL_USB, "armpll3", NULL, CLK_IS_ROOT, 1440000000, },
|
||||
{ HI3620_PLL_HDMI, "armpll4", NULL, CLK_IS_ROOT, 1188000000, },
|
||||
{ HI3620_PLL_GPU, "armpll5", NULL, CLK_IS_ROOT, 1300000000, },
|
||||
{ HI3620_OSC32K, "osc32k", NULL, 0, 32768, },
|
||||
{ HI3620_OSC26M, "osc26m", NULL, 0, 26000000, },
|
||||
{ HI3620_PCLK, "pclk", NULL, 0, 26000000, },
|
||||
{ HI3620_PLL_ARM0, "armpll0", NULL, 0, 1600000000, },
|
||||
{ HI3620_PLL_ARM1, "armpll1", NULL, 0, 1600000000, },
|
||||
{ HI3620_PLL_PERI, "armpll2", NULL, 0, 1440000000, },
|
||||
{ HI3620_PLL_USB, "armpll3", NULL, 0, 1440000000, },
|
||||
{ HI3620_PLL_HDMI, "armpll4", NULL, 0, 1188000000, },
|
||||
{ HI3620_PLL_GPU, "armpll5", NULL, 0, 1300000000, },
|
||||
};
|
||||
|
||||
/* fixed factor clocks */
|
||||
|
@ -235,7 +235,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev)
|
||||
init.name = "acpu0";
|
||||
init.ops = &hi6220_stub_clk_ops;
|
||||
init.num_parents = 0;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
init.flags = 0;
|
||||
|
||||
clk = devm_clk_register(dev, &stub_clk->hw);
|
||||
if (IS_ERR(clk))
|
||||
|
@ -26,19 +26,19 @@
|
||||
|
||||
/* clocks in AO (always on) controller */
|
||||
static struct hisi_fixed_rate_clock hi6220_fixed_rate_clks[] __initdata = {
|
||||
{ HI6220_REF32K, "ref32k", NULL, CLK_IS_ROOT, 32764, },
|
||||
{ HI6220_CLK_TCXO, "clk_tcxo", NULL, CLK_IS_ROOT, 19200000, },
|
||||
{ HI6220_MMC1_PAD, "mmc1_pad", NULL, CLK_IS_ROOT, 100000000, },
|
||||
{ HI6220_MMC2_PAD, "mmc2_pad", NULL, CLK_IS_ROOT, 100000000, },
|
||||
{ HI6220_MMC0_PAD, "mmc0_pad", NULL, CLK_IS_ROOT, 200000000, },
|
||||
{ HI6220_PLL_BBP, "bbppll0", NULL, CLK_IS_ROOT, 245760000, },
|
||||
{ HI6220_PLL_GPU, "gpupll", NULL, CLK_IS_ROOT, 1000000000,},
|
||||
{ HI6220_PLL1_DDR, "ddrpll1", NULL, CLK_IS_ROOT, 1066000000,},
|
||||
{ HI6220_PLL_SYS, "syspll", NULL, CLK_IS_ROOT, 1200000000,},
|
||||
{ HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, CLK_IS_ROOT, 1200000000,},
|
||||
{ HI6220_DDR_SRC, "ddr_sel_src", NULL, CLK_IS_ROOT, 1200000000,},
|
||||
{ HI6220_PLL_MEDIA, "media_pll", NULL, CLK_IS_ROOT, 1440000000,},
|
||||
{ HI6220_PLL_DDR, "ddrpll0", NULL, CLK_IS_ROOT, 1600000000,},
|
||||
{ HI6220_REF32K, "ref32k", NULL, 0, 32764, },
|
||||
{ HI6220_CLK_TCXO, "clk_tcxo", NULL, 0, 19200000, },
|
||||
{ HI6220_MMC1_PAD, "mmc1_pad", NULL, 0, 100000000, },
|
||||
{ HI6220_MMC2_PAD, "mmc2_pad", NULL, 0, 100000000, },
|
||||
{ HI6220_MMC0_PAD, "mmc0_pad", NULL, 0, 200000000, },
|
||||
{ HI6220_PLL_BBP, "bbppll0", NULL, 0, 245760000, },
|
||||
{ HI6220_PLL_GPU, "gpupll", NULL, 0, 1000000000,},
|
||||
{ HI6220_PLL1_DDR, "ddrpll1", NULL, 0, 1066000000,},
|
||||
{ HI6220_PLL_SYS, "syspll", NULL, 0, 1200000000,},
|
||||
{ HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, 0, 1200000000,},
|
||||
{ HI6220_DDR_SRC, "ddr_sel_src", NULL, 0, 1200000000,},
|
||||
{ HI6220_PLL_MEDIA, "media_pll", NULL, 0, 1440000000,},
|
||||
{ HI6220_PLL_DDR, "ddrpll0", NULL, 0, 1600000000,},
|
||||
};
|
||||
|
||||
static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = {
|
||||
|
@ -36,9 +36,9 @@
|
||||
|
||||
/* fixed rate clocks */
|
||||
static struct hisi_fixed_rate_clock hip04_fixed_rate_clks[] __initdata = {
|
||||
{ HIP04_OSC50M, "osc50m", NULL, CLK_IS_ROOT, 50000000, },
|
||||
{ HIP04_CLK_50M, "clk50m", NULL, CLK_IS_ROOT, 50000000, },
|
||||
{ HIP04_CLK_168M, "clk168m", NULL, CLK_IS_ROOT, 168750000, },
|
||||
{ HIP04_OSC50M, "osc50m", NULL, 0, 50000000, },
|
||||
{ HIP04_CLK_50M, "clk50m", NULL, 0, 50000000, },
|
||||
{ HIP04_CLK_168M, "clk168m", NULL, 0, 168750000, },
|
||||
};
|
||||
|
||||
static void __init hip04_clk_init(struct device_node *np)
|
||||
|
@ -14,36 +14,36 @@
|
||||
#include "clk.h"
|
||||
|
||||
static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = {
|
||||
{ HIX5HD2_FIXED_1200M, "1200m", NULL, CLK_IS_ROOT, 1200000000, },
|
||||
{ HIX5HD2_FIXED_400M, "400m", NULL, CLK_IS_ROOT, 400000000, },
|
||||
{ HIX5HD2_FIXED_48M, "48m", NULL, CLK_IS_ROOT, 48000000, },
|
||||
{ HIX5HD2_FIXED_24M, "24m", NULL, CLK_IS_ROOT, 24000000, },
|
||||
{ HIX5HD2_FIXED_600M, "600m", NULL, CLK_IS_ROOT, 600000000, },
|
||||
{ HIX5HD2_FIXED_300M, "300m", NULL, CLK_IS_ROOT, 300000000, },
|
||||
{ HIX5HD2_FIXED_75M, "75m", NULL, CLK_IS_ROOT, 75000000, },
|
||||
{ HIX5HD2_FIXED_200M, "200m", NULL, CLK_IS_ROOT, 200000000, },
|
||||
{ HIX5HD2_FIXED_100M, "100m", NULL, CLK_IS_ROOT, 100000000, },
|
||||
{ HIX5HD2_FIXED_40M, "40m", NULL, CLK_IS_ROOT, 40000000, },
|
||||
{ HIX5HD2_FIXED_150M, "150m", NULL, CLK_IS_ROOT, 150000000, },
|
||||
{ HIX5HD2_FIXED_1728M, "1728m", NULL, CLK_IS_ROOT, 1728000000, },
|
||||
{ HIX5HD2_FIXED_28P8M, "28p8m", NULL, CLK_IS_ROOT, 28000000, },
|
||||
{ HIX5HD2_FIXED_432M, "432m", NULL, CLK_IS_ROOT, 432000000, },
|
||||
{ HIX5HD2_FIXED_345P6M, "345p6m", NULL, CLK_IS_ROOT, 345000000, },
|
||||
{ HIX5HD2_FIXED_288M, "288m", NULL, CLK_IS_ROOT, 288000000, },
|
||||
{ HIX5HD2_FIXED_60M, "60m", NULL, CLK_IS_ROOT, 60000000, },
|
||||
{ HIX5HD2_FIXED_750M, "750m", NULL, CLK_IS_ROOT, 750000000, },
|
||||
{ HIX5HD2_FIXED_500M, "500m", NULL, CLK_IS_ROOT, 500000000, },
|
||||
{ HIX5HD2_FIXED_54M, "54m", NULL, CLK_IS_ROOT, 54000000, },
|
||||
{ HIX5HD2_FIXED_27M, "27m", NULL, CLK_IS_ROOT, 27000000, },
|
||||
{ HIX5HD2_FIXED_1500M, "1500m", NULL, CLK_IS_ROOT, 1500000000, },
|
||||
{ HIX5HD2_FIXED_375M, "375m", NULL, CLK_IS_ROOT, 375000000, },
|
||||
{ HIX5HD2_FIXED_187M, "187m", NULL, CLK_IS_ROOT, 187000000, },
|
||||
{ HIX5HD2_FIXED_250M, "250m", NULL, CLK_IS_ROOT, 250000000, },
|
||||
{ HIX5HD2_FIXED_125M, "125m", NULL, CLK_IS_ROOT, 125000000, },
|
||||
{ HIX5HD2_FIXED_2P02M, "2m", NULL, CLK_IS_ROOT, 2000000, },
|
||||
{ HIX5HD2_FIXED_50M, "50m", NULL, CLK_IS_ROOT, 50000000, },
|
||||
{ HIX5HD2_FIXED_25M, "25m", NULL, CLK_IS_ROOT, 25000000, },
|
||||
{ HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, },
|
||||
{ HIX5HD2_FIXED_1200M, "1200m", NULL, 0, 1200000000, },
|
||||
{ HIX5HD2_FIXED_400M, "400m", NULL, 0, 400000000, },
|
||||
{ HIX5HD2_FIXED_48M, "48m", NULL, 0, 48000000, },
|
||||
{ HIX5HD2_FIXED_24M, "24m", NULL, 0, 24000000, },
|
||||
{ HIX5HD2_FIXED_600M, "600m", NULL, 0, 600000000, },
|
||||
{ HIX5HD2_FIXED_300M, "300m", NULL, 0, 300000000, },
|
||||
{ HIX5HD2_FIXED_75M, "75m", NULL, 0, 75000000, },
|
||||
{ HIX5HD2_FIXED_200M, "200m", NULL, 0, 200000000, },
|
||||
{ HIX5HD2_FIXED_100M, "100m", NULL, 0, 100000000, },
|
||||
{ HIX5HD2_FIXED_40M, "40m", NULL, 0, 40000000, },
|
||||
{ HIX5HD2_FIXED_150M, "150m", NULL, 0, 150000000, },
|
||||
{ HIX5HD2_FIXED_1728M, "1728m", NULL, 0, 1728000000, },
|
||||
{ HIX5HD2_FIXED_28P8M, "28p8m", NULL, 0, 28000000, },
|
||||
{ HIX5HD2_FIXED_432M, "432m", NULL, 0, 432000000, },
|
||||
{ HIX5HD2_FIXED_345P6M, "345p6m", NULL, 0, 345000000, },
|
||||
{ HIX5HD2_FIXED_288M, "288m", NULL, 0, 288000000, },
|
||||
{ HIX5HD2_FIXED_60M, "60m", NULL, 0, 60000000, },
|
||||
{ HIX5HD2_FIXED_750M, "750m", NULL, 0, 750000000, },
|
||||
{ HIX5HD2_FIXED_500M, "500m", NULL, 0, 500000000, },
|
||||
{ HIX5HD2_FIXED_54M, "54m", NULL, 0, 54000000, },
|
||||
{ HIX5HD2_FIXED_27M, "27m", NULL, 0, 27000000, },
|
||||
{ HIX5HD2_FIXED_1500M, "1500m", NULL, 0, 1500000000, },
|
||||
{ HIX5HD2_FIXED_375M, "375m", NULL, 0, 375000000, },
|
||||
{ HIX5HD2_FIXED_187M, "187m", NULL, 0, 187000000, },
|
||||
{ HIX5HD2_FIXED_250M, "250m", NULL, 0, 250000000, },
|
||||
{ HIX5HD2_FIXED_125M, "125m", NULL, 0, 125000000, },
|
||||
{ HIX5HD2_FIXED_2P02M, "2m", NULL, 0, 2000000, },
|
||||
{ HIX5HD2_FIXED_50M, "50m", NULL, 0, 50000000, },
|
||||
{ HIX5HD2_FIXED_25M, "25m", NULL, 0, 25000000, },
|
||||
{ HIX5HD2_FIXED_83M, "83m", NULL, 0, 83333333, },
|
||||
};
|
||||
|
||||
static const char *const sfc_mux_p[] __initconst = {
|
||||
|
@ -34,7 +34,9 @@ static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
|
||||
static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
|
||||
static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
|
||||
static const char *gpu_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *pre_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
|
||||
static const char *gpu2d_core_sels_2[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m",};
|
||||
static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
|
||||
static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
|
||||
static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
|
||||
@ -44,15 +46,24 @@ static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di
|
||||
static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
|
||||
static const char *ipu1_di0_sels_2[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
|
||||
static const char *ipu1_di1_sels_2[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
|
||||
static const char *ipu2_di0_sels_2[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
|
||||
static const char *ipu2_di1_sels_2[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", };
|
||||
static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
|
||||
static const char *pcie_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", };
|
||||
static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
|
||||
static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
|
||||
static const char *enfc_sels_2[] = {"pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", };
|
||||
static const char *eim_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
|
||||
static const char *eim_slow_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
|
||||
static const char *vdo_axi_sels[] = { "axi", "ahb", };
|
||||
static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
|
||||
static const char *uart_sels[] = { "pll3_80m", "osc", };
|
||||
static const char *ipg_per_sels[] = { "ipg", "osc", };
|
||||
static const char *ecspi_sels[] = { "pll3_60m", "osc", };
|
||||
static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", };
|
||||
static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
|
||||
"dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
|
||||
"ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", };
|
||||
@ -121,12 +132,19 @@ static unsigned int share_count_ssi2;
|
||||
static unsigned int share_count_ssi3;
|
||||
static unsigned int share_count_mipi_core_cfg;
|
||||
static unsigned int share_count_spdif;
|
||||
static unsigned int share_count_prg0;
|
||||
static unsigned int share_count_prg1;
|
||||
|
||||
static inline int clk_on_imx6q(void)
|
||||
{
|
||||
return of_machine_is_compatible("fsl,imx6q");
|
||||
}
|
||||
|
||||
static inline int clk_on_imx6qp(void)
|
||||
{
|
||||
return of_machine_is_compatible("fsl,imx6qp");
|
||||
}
|
||||
|
||||
static inline int clk_on_imx6dl(void)
|
||||
{
|
||||
return of_machine_is_compatible("fsl,imx6dl");
|
||||
@ -265,7 +283,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
|
||||
clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
|
||||
clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
|
||||
if (clk_on_imx6dl()) {
|
||||
if (clk_on_imx6dl() || clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1);
|
||||
clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
|
||||
}
|
||||
@ -294,7 +312,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
|
||||
clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
|
||||
}
|
||||
clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
|
||||
clk[IMX6QDL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
|
||||
clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels));
|
||||
clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
|
||||
clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2));
|
||||
} else {
|
||||
clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
|
||||
}
|
||||
clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels));
|
||||
clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
|
||||
clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
|
||||
@ -305,22 +331,40 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
|
||||
clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
|
||||
clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
|
||||
clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup);
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels_2, ARRAY_SIZE(ipu1_di0_sels_2), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels_2, ARRAY_SIZE(ipu1_di1_sels_2), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels_2, ARRAY_SIZE(ipu2_di0_sels_2), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels_2, ARRAY_SIZE(ipu2_di1_sels_2), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels_2, ARRAY_SIZE(enfc_sels_2));
|
||||
clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels));
|
||||
clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
|
||||
clk[IMX6QDL_CLK_PRE_AXI] = imx_clk_mux("pre_axi", base + 0x18, 1, 1, pre_axi_sels, ARRAY_SIZE(pre_axi_sels));
|
||||
} else {
|
||||
clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
|
||||
clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup);
|
||||
}
|
||||
clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels));
|
||||
clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels));
|
||||
clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
|
||||
@ -335,23 +379,33 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
|
||||
clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
|
||||
clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
|
||||
clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
|
||||
clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
|
||||
clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3);
|
||||
clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
|
||||
clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
|
||||
clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
|
||||
clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
|
||||
clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_IPG_PER] = imx_clk_divider("ipg_per", "ipg_per_sel", base + 0x1c, 0, 6);
|
||||
clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6);
|
||||
clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "can_sel", base + 0x20, 2, 6);
|
||||
clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6);
|
||||
clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0", 2, 7);
|
||||
clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7);
|
||||
} else {
|
||||
clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
|
||||
clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60", base + 0x20, 2, 6);
|
||||
clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
|
||||
clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
|
||||
clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
|
||||
}
|
||||
clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
|
||||
clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
|
||||
clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3);
|
||||
clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
|
||||
clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
|
||||
clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
|
||||
clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
|
||||
clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
|
||||
clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
|
||||
clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
|
||||
clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
|
||||
@ -364,15 +418,19 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
|
||||
clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
|
||||
clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
|
||||
clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
|
||||
clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
|
||||
clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
|
||||
clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
|
||||
clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
|
||||
clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
|
||||
clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
|
||||
clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup);
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3);
|
||||
clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
|
||||
} else {
|
||||
clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup);
|
||||
clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup);
|
||||
}
|
||||
clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3);
|
||||
clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
|
||||
clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
|
||||
@ -380,7 +438,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
/* name parent_name reg shift width busy: reg, shift */
|
||||
clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
|
||||
clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
|
||||
clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_MMDC_CH1_AXI_CG] = imx_clk_gate("mmdc_ch1_axi_cg", "periph2", base + 0x4, 18);
|
||||
clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "mmdc_ch1_axi_cg", base + 0x14, 3, 3, base + 0x48, 2);
|
||||
} else {
|
||||
clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
|
||||
}
|
||||
clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
|
||||
clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
|
||||
|
||||
@ -432,8 +495,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
|
||||
clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
|
||||
clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
|
||||
clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
|
||||
clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_sel", base + 0x74, 12);
|
||||
clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_sel", base + 0x74, 14);
|
||||
} else {
|
||||
clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
|
||||
clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
|
||||
}
|
||||
clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
|
||||
clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg);
|
||||
clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg);
|
||||
@ -482,6 +550,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
|
||||
clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12);
|
||||
clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14);
|
||||
if (clk_on_imx6qp()) {
|
||||
clk[IMX6QDL_CLK_PRE0] = imx_clk_gate2("pre0", "pre_axi", base + 0x80, 16);
|
||||
clk[IMX6QDL_CLK_PRE1] = imx_clk_gate2("pre1", "pre_axi", base + 0x80, 18);
|
||||
clk[IMX6QDL_CLK_PRE2] = imx_clk_gate2("pre2", "pre_axi", base + 0x80, 20);
|
||||
clk[IMX6QDL_CLK_PRE3] = imx_clk_gate2("pre3", "pre_axi", base + 0x80, 22);
|
||||
clk[IMX6QDL_CLK_PRG0_AXI] = imx_clk_gate2_shared("prg0_axi", "ipu1_podf", base + 0x80, 24, &share_count_prg0);
|
||||
clk[IMX6QDL_CLK_PRG1_AXI] = imx_clk_gate2_shared("prg1_axi", "ipu2_podf", base + 0x80, 26, &share_count_prg1);
|
||||
clk[IMX6QDL_CLK_PRG0_APB] = imx_clk_gate2_shared("prg0_apb", "ipg", base + 0x80, 24, &share_count_prg0);
|
||||
clk[IMX6QDL_CLK_PRG1_APB] = imx_clk_gate2_shared("prg1_apb", "ipg", base + 0x80, 26, &share_count_prg1);
|
||||
}
|
||||
clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
|
||||
clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
|
||||
|
||||
|
@ -157,9 +157,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clk_set_parent(clks[IMX6UL_PLL7_BYPASS], clks[IMX6UL_CLK_PLL7]);
|
||||
|
||||
clks[IMX6UL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
|
||||
clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
|
||||
clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
|
||||
clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
|
||||
clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
|
||||
clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
|
||||
clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
|
||||
clks[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
|
||||
clks[IMX6UL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
|
||||
clks[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
|
||||
@ -196,8 +196,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
|
||||
|
||||
clks[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20);
|
||||
clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
|
||||
clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
|
||||
clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
|
||||
clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
|
||||
|
||||
clks[IMX6UL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
@ -210,8 +210,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
|
||||
/* name parent_name mult div */
|
||||
clks[IMX6UL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
|
||||
clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
|
||||
clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
|
||||
clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
|
||||
clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
|
||||
clks[IMX6UL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
|
||||
|
||||
np = ccm_node;
|
||||
@ -219,34 +219,34 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
WARN_ON(!base);
|
||||
|
||||
clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels));
|
||||
clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
|
||||
clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
|
||||
clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
|
||||
clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
|
||||
clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
|
||||
clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
|
||||
clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
|
||||
clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
|
||||
clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0);
|
||||
clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
|
||||
clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
|
||||
clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
|
||||
clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
|
||||
clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
|
||||
clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
|
||||
clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels));
|
||||
clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels));
|
||||
clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels));
|
||||
clks[IMX6UL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clks[IMX6UL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels));
|
||||
clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels));
|
||||
clks[IMX6UL_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels));
|
||||
clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels));
|
||||
clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
|
||||
clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
|
||||
clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
|
||||
clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels));
|
||||
clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
|
||||
clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
|
||||
clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
|
||||
clks[IMX6UL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
|
||||
clks[IMX6UL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels));
|
||||
clks[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
|
||||
clks[IMX6UL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
|
||||
clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels));
|
||||
clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels));
|
||||
clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels));
|
||||
clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels));
|
||||
clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
|
||||
clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
|
||||
clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
|
||||
clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
|
||||
|
||||
clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
|
||||
clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
|
||||
@ -259,11 +259,11 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
|
||||
clks[IMX6UL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
|
||||
|
||||
clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
|
||||
clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
|
||||
clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
|
||||
clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
|
||||
clks[IMX6UL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
|
||||
clks[IMX6UL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3);
|
||||
clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
|
||||
clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
|
||||
clks[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
|
||||
clks[IMX6UL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
|
||||
clks[IMX6UL_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6);
|
||||
@ -287,14 +287,14 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3);
|
||||
clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
|
||||
|
||||
clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
|
||||
clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
|
||||
clks[IMX6UL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
|
||||
clks[IMX6UL_CLK_AXI_PODF] = imx_clk_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
|
||||
clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
|
||||
|
||||
/* CCGR0 */
|
||||
clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
|
||||
clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
|
||||
clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
|
||||
clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
|
||||
clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4);
|
||||
clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc);
|
||||
clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc);
|
||||
@ -302,7 +302,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
|
||||
clks[IMX6UL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
|
||||
clks[IMX6UL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
|
||||
clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
|
||||
clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
|
||||
clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
|
||||
clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20);
|
||||
clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x68, 24);
|
||||
@ -331,7 +331,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
|
||||
clks[IMX6UL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
|
||||
clks[IMX6UL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
|
||||
clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
|
||||
clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
|
||||
clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
|
||||
clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14);
|
||||
clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28);
|
||||
@ -365,6 +365,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
/* CCGR5 */
|
||||
clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
|
||||
clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
|
||||
clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8);
|
||||
clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10);
|
||||
clks[IMX6UL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
|
||||
clks[IMX6UL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
|
||||
@ -391,10 +392,10 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_CLK_UART8_IPG] = imx_clk_gate2("uart8_ipg", "ipg", base + 0x80, 14);
|
||||
clks[IMX6UL_CLK_UART8_SERIAL] = imx_clk_gate2("uart8_serial", "uart_podf", base + 0x80, 14);
|
||||
clks[IMX6UL_CLK_WDOG3] = imx_clk_gate2("wdog3", "ipg", base + 0x80, 20);
|
||||
clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
|
||||
clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
|
||||
clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
|
||||
clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
|
||||
clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("Pwm7", "perclk", base + 0x80, 30);
|
||||
clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
|
||||
|
||||
/* mask handshake of mmdc */
|
||||
writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
|
||||
|
@ -87,7 +87,7 @@ struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
|
||||
|
||||
static inline struct clk *imx_clk_fixed(const char *name, int rate)
|
||||
{
|
||||
return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
|
||||
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
|
||||
|
@ -58,8 +58,8 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
|
||||
for (i = 0; i < num; i++) {
|
||||
const struct mtk_fixed_clk *rc = &clks[i];
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, rc->name, rc->parent,
|
||||
rc->parent ? 0 : CLK_IS_ROOT, rc->rate);
|
||||
clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
|
||||
rc->rate);
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("Failed to register clk %s: %ld\n",
|
||||
|
@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
|
||||
}
|
||||
|
||||
void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
|
||||
size_t nr_confs,
|
||||
unsigned int nr_confs,
|
||||
void __iomem *clk_base)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -11,7 +11,6 @@ config ARMADA_370_CLK
|
||||
bool
|
||||
select MVEBU_CLK_COMMON
|
||||
select MVEBU_CLK_CPU
|
||||
select MVEBU_CLK_COREDIV
|
||||
|
||||
config ARMADA_375_CLK
|
||||
bool
|
||||
@ -29,7 +28,6 @@ config ARMADA_XP_CLK
|
||||
bool
|
||||
select MVEBU_CLK_COMMON
|
||||
select MVEBU_CLK_CPU
|
||||
select MVEBU_CLK_COREDIV
|
||||
|
||||
config DOVE_CLK
|
||||
bool
|
||||
|
@ -137,8 +137,8 @@ void __init mvebu_coreclk_setup(struct device_node *np,
|
||||
of_property_read_string_index(np, "clock-output-names", 0,
|
||||
&tclk_name);
|
||||
rate = desc->get_tclk_freq(base);
|
||||
clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
|
||||
CLK_IS_ROOT, rate);
|
||||
clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL, 0,
|
||||
rate);
|
||||
WARN_ON(IS_ERR(clk_data.clks[0]));
|
||||
|
||||
/* Register CPU clock */
|
||||
@ -150,8 +150,8 @@ void __init mvebu_coreclk_setup(struct device_node *np,
|
||||
&& desc->is_sscg_enabled(base))
|
||||
rate = desc->fix_sscg_deviation(rate);
|
||||
|
||||
clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
|
||||
CLK_IS_ROOT, rate);
|
||||
clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, 0,
|
||||
rate);
|
||||
WARN_ON(IS_ERR(clk_data.clks[1]));
|
||||
|
||||
/* Register fixed-factor clocks derived from CPU clock */
|
||||
@ -174,8 +174,7 @@ void __init mvebu_coreclk_setup(struct device_node *np,
|
||||
2 + desc->num_ratios, &name);
|
||||
rate = desc->get_refclk_freq(base);
|
||||
clk_data.clks[2 + desc->num_ratios] =
|
||||
clk_register_fixed_rate(NULL, name, NULL,
|
||||
CLK_IS_ROOT, rate);
|
||||
clk_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
WARN_ON(IS_ERR(clk_data.clks[2 + desc->num_ratios]));
|
||||
}
|
||||
|
||||
|
@ -225,8 +225,7 @@ static int dove_divider_init(struct device *dev, void __iomem *base,
|
||||
* Create the core PLL clock. We treat this as a fixed rate
|
||||
* clock as we don't know any better, and documentation is sparse.
|
||||
*/
|
||||
clk = clk_register_fixed_rate(dev, core_pll[0], NULL, CLK_IS_ROOT,
|
||||
2000000000UL);
|
||||
clk = clk_register_fixed_rate(dev, core_pll[0], NULL, 0, 2000000000UL);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
|
@ -38,7 +38,7 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name,
|
||||
|
||||
static inline struct clk *mxs_clk_fixed(const char *name, int rate)
|
||||
{
|
||||
return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
|
||||
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
}
|
||||
|
||||
static inline struct clk *mxs_clk_gate(const char *name,
|
||||
|
@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o
|
||||
obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o
|
||||
obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-creg.o
|
||||
obj-$(CONFIG_ARCH_LPC32XX) += clk-lpc32xx.o
|
||||
|
@ -605,7 +605,7 @@ static void __init lpc18xx_cgu_register_source_clks(struct device_node *np,
|
||||
|
||||
/* Register the internal 12 MHz RC oscillator (IRC) */
|
||||
clk = clk_register_fixed_rate(NULL, clk_src_names[CLK_SRC_IRC],
|
||||
NULL, CLK_IS_ROOT, 12000000);
|
||||
NULL, 0, 12000000);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: failed to register irc clk\n", __func__);
|
||||
|
||||
|
226
drivers/clk/nxp/clk-lpc18xx-creg.c
Normal file
226
drivers/clk/nxp/clk-lpc18xx-creg.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Clk driver for NXP LPC18xx/43xx Configuration Registers (CREG)
|
||||
*
|
||||
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define LPC18XX_CREG_CREG0 0x004
|
||||
#define LPC18XX_CREG_CREG0_EN1KHZ BIT(0)
|
||||
#define LPC18XX_CREG_CREG0_EN32KHZ BIT(1)
|
||||
#define LPC18XX_CREG_CREG0_RESET32KHZ BIT(2)
|
||||
#define LPC18XX_CREG_CREG0_PD32KHZ BIT(3)
|
||||
|
||||
#define to_clk_creg(_hw) container_of(_hw, struct clk_creg_data, hw)
|
||||
|
||||
enum {
|
||||
CREG_CLK_1KHZ,
|
||||
CREG_CLK_32KHZ,
|
||||
CREG_CLK_MAX,
|
||||
};
|
||||
|
||||
struct clk_creg_data {
|
||||
struct clk_hw hw;
|
||||
const char *name;
|
||||
struct regmap *reg;
|
||||
unsigned int en_mask;
|
||||
const struct clk_ops *ops;
|
||||
};
|
||||
|
||||
#define CREG_CLK(_name, _emask, _ops) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.en_mask = LPC18XX_CREG_CREG0_##_emask, \
|
||||
.ops = &_ops, \
|
||||
}
|
||||
|
||||
static int clk_creg_32k_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_creg_data *creg = to_clk_creg(hw);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
|
||||
LPC18XX_CREG_CREG0_PD32KHZ |
|
||||
LPC18XX_CREG_CREG0_RESET32KHZ, 0);
|
||||
|
||||
/*
|
||||
* Powering up the 32k oscillator takes a long while
|
||||
* and sadly there aren't any status bit to poll.
|
||||
*/
|
||||
msleep(2500);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_creg_32k_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_creg_data *creg = to_clk_creg(hw);
|
||||
|
||||
regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
|
||||
LPC18XX_CREG_CREG0_PD32KHZ,
|
||||
LPC18XX_CREG_CREG0_PD32KHZ);
|
||||
}
|
||||
|
||||
static int clk_creg_32k_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_creg_data *creg = to_clk_creg(hw);
|
||||
u32 reg;
|
||||
|
||||
regmap_read(creg->reg, LPC18XX_CREG_CREG0, ®);
|
||||
|
||||
return !(reg & LPC18XX_CREG_CREG0_PD32KHZ) &&
|
||||
!(reg & LPC18XX_CREG_CREG0_RESET32KHZ);
|
||||
}
|
||||
|
||||
static unsigned long clk_creg_1k_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return parent_rate / 32;
|
||||
}
|
||||
|
||||
static int clk_creg_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_creg_data *creg = to_clk_creg(hw);
|
||||
|
||||
return regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
|
||||
creg->en_mask, creg->en_mask);
|
||||
}
|
||||
|
||||
static void clk_creg_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_creg_data *creg = to_clk_creg(hw);
|
||||
|
||||
regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0,
|
||||
creg->en_mask, 0);
|
||||
}
|
||||
|
||||
static int clk_creg_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_creg_data *creg = to_clk_creg(hw);
|
||||
u32 reg;
|
||||
|
||||
regmap_read(creg->reg, LPC18XX_CREG_CREG0, ®);
|
||||
|
||||
return !!(reg & creg->en_mask);
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_creg_32k = {
|
||||
.enable = clk_creg_enable,
|
||||
.disable = clk_creg_disable,
|
||||
.is_enabled = clk_creg_is_enabled,
|
||||
.prepare = clk_creg_32k_prepare,
|
||||
.unprepare = clk_creg_32k_unprepare,
|
||||
.is_prepared = clk_creg_32k_is_prepared,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_creg_1k = {
|
||||
.enable = clk_creg_enable,
|
||||
.disable = clk_creg_disable,
|
||||
.is_enabled = clk_creg_is_enabled,
|
||||
.recalc_rate = clk_creg_1k_recalc_rate,
|
||||
};
|
||||
|
||||
static struct clk_creg_data clk_creg_clocks[] = {
|
||||
[CREG_CLK_1KHZ] = CREG_CLK("1khz_clk", EN1KHZ, clk_creg_1k),
|
||||
[CREG_CLK_32KHZ] = CREG_CLK("32khz_clk", EN32KHZ, clk_creg_32k),
|
||||
};
|
||||
|
||||
static struct clk *clk_register_creg_clk(struct device *dev,
|
||||
struct clk_creg_data *creg_clk,
|
||||
const char **parent_name,
|
||||
struct regmap *syscon)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
|
||||
init.ops = creg_clk->ops;
|
||||
init.name = creg_clk->name;
|
||||
init.parent_names = parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
creg_clk->reg = syscon;
|
||||
creg_clk->hw.init = &init;
|
||||
|
||||
if (dev)
|
||||
return devm_clk_register(dev, &creg_clk->hw);
|
||||
|
||||
return clk_register(NULL, &creg_clk->hw);
|
||||
}
|
||||
|
||||
static struct clk *clk_creg_early[CREG_CLK_MAX];
|
||||
static struct clk_onecell_data clk_creg_early_data = {
|
||||
.clks = clk_creg_early,
|
||||
.clk_num = CREG_CLK_MAX,
|
||||
};
|
||||
|
||||
static void __init lpc18xx_creg_clk_init(struct device_node *np)
|
||||
{
|
||||
const char *clk_32khz_parent;
|
||||
struct regmap *syscon;
|
||||
|
||||
syscon = syscon_node_to_regmap(np->parent);
|
||||
if (IS_ERR(syscon)) {
|
||||
pr_err("%s: syscon lookup failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
clk_32khz_parent = of_clk_get_parent_name(np, 0);
|
||||
|
||||
clk_creg_early[CREG_CLK_32KHZ] =
|
||||
clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_32KHZ],
|
||||
&clk_32khz_parent, syscon);
|
||||
clk_creg_early[CREG_CLK_1KHZ] = ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data);
|
||||
}
|
||||
CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init);
|
||||
|
||||
static struct clk *clk_creg[CREG_CLK_MAX];
|
||||
static struct clk_onecell_data clk_creg_data = {
|
||||
.clks = clk_creg,
|
||||
.clk_num = CREG_CLK_MAX,
|
||||
};
|
||||
|
||||
static int lpc18xx_creg_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct regmap *syscon;
|
||||
|
||||
syscon = syscon_node_to_regmap(np->parent);
|
||||
if (IS_ERR(syscon)) {
|
||||
dev_err(&pdev->dev, "syscon lookup failed\n");
|
||||
return PTR_ERR(syscon);
|
||||
}
|
||||
|
||||
clk_creg[CREG_CLK_32KHZ] = clk_creg_early[CREG_CLK_32KHZ];
|
||||
clk_creg[CREG_CLK_1KHZ] =
|
||||
clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_1KHZ],
|
||||
&clk_creg_clocks[CREG_CLK_32KHZ].name,
|
||||
syscon);
|
||||
|
||||
return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id lpc18xx_creg_clk_of_match[] = {
|
||||
{ .compatible = "nxp,lpc1850-creg-clk" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver lpc18xx_creg_clk_driver = {
|
||||
.probe = lpc18xx_creg_clk_probe,
|
||||
.driver = {
|
||||
.name = "lpc18xx-creg-clk",
|
||||
.of_match_table = lpc18xx_creg_clk_of_match,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(lpc18xx_creg_clk_driver);
|
@ -87,7 +87,7 @@ enum {
|
||||
|
||||
enum {
|
||||
/* Start from the last defined clock in dt bindings */
|
||||
LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1,
|
||||
LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_HCLK_PLL + 1,
|
||||
LPC32XX_CLK_ADC_RTC,
|
||||
LPC32XX_CLK_TEST1,
|
||||
LPC32XX_CLK_TEST2,
|
||||
@ -96,7 +96,6 @@ enum {
|
||||
LPC32XX_CLK_OSC,
|
||||
LPC32XX_CLK_SYS,
|
||||
LPC32XX_CLK_PLL397X,
|
||||
LPC32XX_CLK_HCLK_PLL,
|
||||
LPC32XX_CLK_HCLK_DIV_PERIPH,
|
||||
LPC32XX_CLK_HCLK_DIV,
|
||||
LPC32XX_CLK_HCLK,
|
||||
@ -589,7 +588,8 @@ static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
|
||||
u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6;
|
||||
u64 m_i, o = rate, i = *parent_rate, d = (u64)rate << 6;
|
||||
u64 m = 0, n = 0, p = 0;
|
||||
int p_i, n_i;
|
||||
|
||||
pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate);
|
||||
@ -1429,6 +1429,8 @@ static struct clk * __init lpc32xx_clk_register(u32 id)
|
||||
hw = &clk_hw->hw0.div.hw;
|
||||
else if (clk_hw->type == CLK_GATE)
|
||||
hw = &clk_hw->hw0.gate.hw;
|
||||
else
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
hw->init = &clk_init;
|
||||
clk = clk_register(NULL, hw);
|
||||
@ -1515,7 +1517,7 @@ static void __init lpc32xx_clk_init(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < LPC32XX_CLK_MAX; i++) {
|
||||
for (i = 1; i < LPC32XX_CLK_MAX; i++) {
|
||||
clk[i] = lpc32xx_clk_register(i);
|
||||
if (IS_ERR(clk[i])) {
|
||||
pr_err("failed to register %s clock: %ld\n",
|
||||
@ -1526,9 +1528,6 @@ static void __init lpc32xx_clk_init(struct device_node *np)
|
||||
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
|
||||
/* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */
|
||||
clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000);
|
||||
|
||||
/* Set 48MHz rate of USB PLL clock */
|
||||
clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000);
|
||||
|
||||
@ -1555,7 +1554,7 @@ static void __init lpc32xx_usb_clk_init(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) {
|
||||
for (i = 1; i < LPC32XX_USB_CLK_MAX; i++) {
|
||||
usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET);
|
||||
if (IS_ERR(usb_clk[i])) {
|
||||
pr_err("failed to register %s clock: %ld\n",
|
||||
|
@ -200,12 +200,10 @@ static void __init pxa25x_register_core(void)
|
||||
static void __init pxa25x_register_plls(void)
|
||||
{
|
||||
clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
3686400);
|
||||
CLK_GET_RATE_NOCACHE, 3686400);
|
||||
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
32768);
|
||||
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
|
||||
CLK_GET_RATE_NOCACHE, 32768);
|
||||
clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
|
||||
clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz",
|
||||
0, 26, 1);
|
||||
clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz",
|
||||
|
@ -208,12 +208,12 @@ MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base");
|
||||
static void __init pxa27x_register_plls(void)
|
||||
{
|
||||
clk_register_fixed_rate(NULL, "osc_13mhz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
CLK_GET_RATE_NOCACHE,
|
||||
13 * MHz);
|
||||
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
CLK_GET_RATE_NOCACHE,
|
||||
32768 * KHz);
|
||||
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
|
||||
clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
|
||||
clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1);
|
||||
}
|
||||
|
||||
|
@ -284,15 +284,15 @@ static void __init pxa3xx_register_core(void)
|
||||
static void __init pxa3xx_register_plls(void)
|
||||
{
|
||||
clk_register_fixed_rate(NULL, "osc_13mhz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
CLK_GET_RATE_NOCACHE,
|
||||
13 * MHz);
|
||||
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
CLK_GET_RATE_NOCACHE,
|
||||
32768);
|
||||
clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL,
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
|
||||
CLK_GET_RATE_NOCACHE,
|
||||
120 * MHz);
|
||||
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
|
||||
clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
|
||||
clk_register_fixed_factor(NULL, "spll_624mhz", "osc_13mhz", 0, 48, 1);
|
||||
clk_register_fixed_factor(NULL, "ring_osc_60mhz", "ring_osc_120mhz",
|
||||
0, 1, 2);
|
||||
|
@ -28,6 +28,14 @@ config APQ_MMCC_8084
|
||||
Say Y if you want to support multimedia devices such as display,
|
||||
graphics, video encode/decode, camera, etc.
|
||||
|
||||
config IPQ_GCC_4019
|
||||
tristate "IPQ4019 Global Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the global clock controller on ipq4019 devices.
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
i2c, USB, SD/eMMC, etc.
|
||||
|
||||
config IPQ_GCC_806X
|
||||
tristate "IPQ806x Global Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
|
@ -14,6 +14,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
|
||||
|
||||
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
|
||||
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
|
||||
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
||||
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
|
||||
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
|
||||
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
|
||||
|
@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return ret;
|
||||
|
||||
src = ns_to_src(&rcg->s, ns);
|
||||
f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1;
|
||||
|
||||
for (i = 0; i < num_parents; i++) {
|
||||
if (src == rcg->s.parent_map[i].cfg) {
|
||||
@ -647,6 +646,9 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
}
|
||||
}
|
||||
|
||||
/* bypass the pre divider */
|
||||
f.pre_div = 1;
|
||||
|
||||
/* let us find appropriate m/n values for this */
|
||||
for (; frac->num; frac++) {
|
||||
request = (rate * frac->den) / frac->num;
|
||||
|
@ -119,7 +119,6 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
|
||||
fixed->hw.init = &init_data;
|
||||
|
||||
init_data.name = path;
|
||||
init_data.flags = CLK_IS_ROOT;
|
||||
init_data.ops = &clk_fixed_rate_ops;
|
||||
|
||||
clk = devm_clk_register(dev, &fixed->hw);
|
||||
@ -185,6 +184,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
|
||||
struct clk **clks;
|
||||
struct qcom_reset_controller *reset;
|
||||
struct qcom_cc *cc;
|
||||
struct gdsc_desc *scd;
|
||||
size_t num_clks = desc->num_clks;
|
||||
struct clk_regmap **rclks = desc->clks;
|
||||
|
||||
@ -213,7 +213,11 @@ int qcom_cc_really_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node);
|
||||
ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider,
|
||||
pdev->dev.of_node);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reset = &cc->reset;
|
||||
reset->rcdev.of_node = dev->of_node;
|
||||
@ -227,18 +231,28 @@ int qcom_cc_really_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev);
|
||||
ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister,
|
||||
&reset->rcdev);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (desc->gdscs && desc->num_gdscs) {
|
||||
ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
|
||||
&reset->rcdev, regmap);
|
||||
scd = devm_kzalloc(dev, sizeof(*scd), GFP_KERNEL);
|
||||
if (!scd)
|
||||
return -ENOMEM;
|
||||
scd->dev = dev;
|
||||
scd->scs = desc->gdscs;
|
||||
scd->num = desc->num_gdscs;
|
||||
ret = gdsc_register(scd, &reset->rcdev, regmap);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister,
|
||||
scd);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
devm_add_action(dev, qcom_cc_gdsc_unregister, dev);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
|
||||
|
1354
drivers/clk/qcom/gcc-ipq4019.c
Normal file
1354
drivers/clk/qcom/gcc-ipq4019.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -890,7 +890,6 @@ static struct clk_branch gsbi1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -906,7 +905,6 @@ static struct clk_branch gsbi2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -922,7 +920,6 @@ static struct clk_branch gsbi4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -938,7 +935,6 @@ static struct clk_branch gsbi5_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi5_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -954,7 +950,6 @@ static struct clk_branch gsbi6_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi6_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -970,7 +965,6 @@ static struct clk_branch gsbi7_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi7_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1144,7 +1138,6 @@ static struct clk_branch pmem_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmem_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1308,7 +1301,6 @@ static struct clk_branch sdc1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1324,7 +1316,6 @@ static struct clk_branch sdc3_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc3_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1394,7 +1385,6 @@ static struct clk_branch tsif_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "tsif_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1410,7 +1400,6 @@ static struct clk_branch dma_bam_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dma_bam_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1425,7 +1414,6 @@ static struct clk_branch adm0_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm0_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1442,7 +1430,6 @@ static struct clk_branch adm0_pbus_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm0_pbus_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1457,7 +1444,6 @@ static struct clk_branch pmic_arb0_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_arb0_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1472,7 +1458,6 @@ static struct clk_branch pmic_arb1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_arb1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1487,7 +1472,6 @@ static struct clk_branch pmic_ssbi2_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_ssbi2_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1504,7 +1488,6 @@ static struct clk_branch rpm_msg_ram_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "rpm_msg_ram_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1563,7 +1546,6 @@ static struct clk_branch pcie_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1577,7 +1559,6 @@ static struct clk_branch pcie_aux_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_aux_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1591,7 +1572,6 @@ static struct clk_branch pcie_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1605,7 +1585,6 @@ static struct clk_branch pcie_phy_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_phy_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1659,7 +1638,6 @@ static struct clk_branch pcie1_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie1_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1673,7 +1651,6 @@ static struct clk_branch pcie1_aux_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie1_aux_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1687,7 +1664,6 @@ static struct clk_branch pcie1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1701,7 +1677,6 @@ static struct clk_branch pcie1_phy_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie1_phy_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1755,7 +1730,6 @@ static struct clk_branch pcie2_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie2_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1769,7 +1743,6 @@ static struct clk_branch pcie2_aux_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie2_aux_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1783,7 +1756,6 @@ static struct clk_branch pcie2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1797,7 +1769,6 @@ static struct clk_branch pcie2_phy_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie2_phy_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1887,7 +1858,6 @@ static struct clk_branch sata_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sata_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1901,7 +1871,6 @@ static struct clk_branch sata_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sata_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1915,7 +1884,6 @@ static struct clk_branch sfab_sata_s_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sfab_sata_s_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1929,7 +1897,6 @@ static struct clk_branch sata_phy_cfg_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sata_phy_cfg_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2139,7 +2106,6 @@ static struct clk_branch usb_hs1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hs1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2218,7 +2184,6 @@ static struct clk_branch usb_fs1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_fs1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2234,7 +2199,6 @@ static struct clk_branch ebi2_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ebi2_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2248,7 +2212,6 @@ static struct clk_branch ebi2_aon_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ebi2_always_on_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1479,7 +1479,6 @@ static struct clk_branch pmem_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmem_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2027,7 +2026,6 @@ static struct clk_branch gsbi1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2041,7 +2039,6 @@ static struct clk_branch gsbi2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2055,7 +2052,6 @@ static struct clk_branch gsbi3_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi3_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2069,7 +2065,6 @@ static struct clk_branch gsbi4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2083,7 +2078,6 @@ static struct clk_branch gsbi5_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi5_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2097,7 +2091,6 @@ static struct clk_branch gsbi6_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi6_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2111,7 +2104,6 @@ static struct clk_branch gsbi7_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi7_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2125,7 +2117,6 @@ static struct clk_branch gsbi8_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi8_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2139,7 +2130,6 @@ static struct clk_branch gsbi9_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi9_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2153,7 +2143,6 @@ static struct clk_branch gsbi10_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi10_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2167,7 +2156,6 @@ static struct clk_branch gsbi11_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi11_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2181,7 +2169,6 @@ static struct clk_branch gsbi12_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi12_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2195,7 +2182,6 @@ static struct clk_branch tsif_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "tsif_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2209,7 +2195,6 @@ static struct clk_branch usb_fs1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_fs1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2223,7 +2208,6 @@ static struct clk_branch usb_fs2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_fs2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2237,7 +2221,6 @@ static struct clk_branch usb_hs1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hs1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2251,7 +2234,6 @@ static struct clk_branch sdc1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2265,7 +2247,6 @@ static struct clk_branch sdc2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2279,7 +2260,6 @@ static struct clk_branch sdc3_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc3_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2293,7 +2273,6 @@ static struct clk_branch sdc4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2307,7 +2286,6 @@ static struct clk_branch sdc5_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc5_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2322,7 +2300,6 @@ static struct clk_branch adm0_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm0_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2337,7 +2314,6 @@ static struct clk_branch adm0_pbus_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm0_pbus_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2352,7 +2328,6 @@ static struct clk_branch adm1_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm1_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2367,7 +2342,6 @@ static struct clk_branch adm1_pbus_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm1_pbus_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2382,7 +2356,6 @@ static struct clk_branch modem_ahb1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "modem_ahb1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2397,7 +2370,6 @@ static struct clk_branch modem_ahb2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "modem_ahb2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2412,7 +2384,6 @@ static struct clk_branch pmic_arb0_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_arb0_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2427,7 +2398,6 @@ static struct clk_branch pmic_arb1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_arb1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2442,7 +2412,6 @@ static struct clk_branch pmic_ssbi2_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_ssbi2_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2459,7 +2428,6 @@ static struct clk_branch rpm_msg_ram_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "rpm_msg_ram_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -2590,6 +2590,23 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
|
||||
.halt_reg = 0x49004,
|
||||
.clkr = {
|
||||
.enable_reg = 0x49004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_mss_q6_bimc_axi_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"bimc_ddr_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_oxili_ahb_clk = {
|
||||
.halt_reg = 0x59028,
|
||||
.clkr = {
|
||||
@ -3227,6 +3244,7 @@ static struct clk_regmap *gcc_msm8916_clocks[] = {
|
||||
[GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
|
||||
[GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
|
||||
[GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
|
||||
[GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gcc_msm8916_gdscs[] = {
|
||||
|
@ -1546,7 +1546,6 @@ static struct clk_branch pmem_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmem_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2143,7 +2142,6 @@ static struct clk_branch usb_hsic_hsio_cal_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hsic_hsio_cal_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2293,7 +2291,6 @@ static struct clk_branch ce1_core_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ce1_core_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2307,7 +2304,6 @@ static struct clk_branch ce1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ce1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2323,7 +2319,6 @@ static struct clk_branch dma_bam_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dma_bam_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2339,7 +2334,6 @@ static struct clk_branch gsbi1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2355,7 +2349,6 @@ static struct clk_branch gsbi2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2371,7 +2364,6 @@ static struct clk_branch gsbi3_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi3_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2387,7 +2379,6 @@ static struct clk_branch gsbi4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2403,7 +2394,6 @@ static struct clk_branch gsbi5_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi5_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2419,7 +2409,6 @@ static struct clk_branch gsbi6_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi6_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2435,7 +2424,6 @@ static struct clk_branch gsbi7_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi7_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2451,7 +2439,6 @@ static struct clk_branch gsbi8_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi8_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2467,7 +2454,6 @@ static struct clk_branch gsbi9_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi9_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2483,7 +2469,6 @@ static struct clk_branch gsbi10_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi10_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2499,7 +2484,6 @@ static struct clk_branch gsbi11_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi11_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2515,7 +2499,6 @@ static struct clk_branch gsbi12_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi12_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2531,7 +2514,6 @@ static struct clk_branch tsif_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "tsif_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2545,7 +2527,6 @@ static struct clk_branch usb_fs1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_fs1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2559,7 +2540,6 @@ static struct clk_branch usb_fs2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_fs2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2575,7 +2555,6 @@ static struct clk_branch usb_hs1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hs1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2589,7 +2568,6 @@ static struct clk_branch usb_hs3_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hs3_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2603,7 +2581,6 @@ static struct clk_branch usb_hs4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hs4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2617,7 +2594,6 @@ static struct clk_branch usb_hsic_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "usb_hsic_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2633,7 +2609,6 @@ static struct clk_branch sdc1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2649,7 +2624,6 @@ static struct clk_branch sdc2_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc2_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2665,7 +2639,6 @@ static struct clk_branch sdc3_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc3_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2681,7 +2654,6 @@ static struct clk_branch sdc4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2697,7 +2669,6 @@ static struct clk_branch sdc5_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sdc5_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2712,7 +2683,6 @@ static struct clk_branch adm0_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm0_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2729,7 +2699,6 @@ static struct clk_branch adm0_pbus_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "adm0_pbus_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2753,7 +2722,7 @@ static struct clk_rcg ce3_src = {
|
||||
},
|
||||
.freq_tbl = clk_tbl_ce3,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2c08,
|
||||
.enable_reg = 0x36c0,
|
||||
.enable_mask = BIT(7),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ce3_src",
|
||||
@ -2769,7 +2738,7 @@ static struct clk_branch ce3_core_clk = {
|
||||
.halt_reg = 0x2fdc,
|
||||
.halt_bit = 5,
|
||||
.clkr = {
|
||||
.enable_reg = 0x36c4,
|
||||
.enable_reg = 0x36cc,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ce3_core_clk",
|
||||
@ -2883,7 +2852,6 @@ static struct clk_branch sata_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sata_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2897,7 +2865,6 @@ static struct clk_branch sata_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sata_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2911,7 +2878,6 @@ static struct clk_branch sfab_sata_s_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sfab_sata_s_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2925,7 +2891,6 @@ static struct clk_branch sata_phy_cfg_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sata_phy_cfg_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2939,7 +2904,6 @@ static struct clk_branch pcie_phy_ref_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_phy_ref_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2953,7 +2917,6 @@ static struct clk_branch pcie_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2967,7 +2930,6 @@ static struct clk_branch pcie_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2982,7 +2944,6 @@ static struct clk_branch pmic_arb0_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_arb0_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2997,7 +2958,6 @@ static struct clk_branch pmic_arb1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_arb1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -3012,7 +2972,6 @@ static struct clk_branch pmic_ssbi2_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pmic_ssbi2_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -3029,7 +2988,6 @@ static struct clk_branch rpm_msg_ram_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "rpm_msg_ram_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1965,7 +1965,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_mss_q6_bimc_axi_clk",
|
||||
.flags = CLK_IS_ROOT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
|
||||
|
||||
@ -1320,7 +1321,7 @@ static struct clk_branch gcc_mmss_bimc_gfx_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_mmss_bimc_gfx_clk",
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
@ -2314,7 +2315,7 @@ static struct clk_branch gcc_bimc_gfx_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_bimc_gfx_clk",
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
@ -2814,7 +2815,6 @@ static struct clk_branch gcc_ufs_sys_clk_core_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_sys_clk_core_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2827,7 +2827,6 @@ static struct clk_branch gcc_ufs_tx_symbol_clk_core_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_tx_symbol_clk_core_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -3059,6 +3058,83 @@ static struct clk_hw *gcc_msm8996_hws[] = {
|
||||
&ufs_ice_core_postdiv_clk_src.hw,
|
||||
};
|
||||
|
||||
static struct gdsc aggre0_noc_gdsc = {
|
||||
.gdscr = 0x81004,
|
||||
.gds_hw_ctrl = 0x81028,
|
||||
.pd = {
|
||||
.name = "aggre0_noc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_aggre0_noc_gdsc = {
|
||||
.gdscr = 0x7d024,
|
||||
.pd = {
|
||||
.name = "hlos1_vote_aggre0_noc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_lpass_adsp_gdsc = {
|
||||
.gdscr = 0x7d034,
|
||||
.pd = {
|
||||
.name = "hlos1_vote_lpass_adsp",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_lpass_core_gdsc = {
|
||||
.gdscr = 0x7d038,
|
||||
.pd = {
|
||||
.name = "hlos1_vote_lpass_core",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc usb30_gdsc = {
|
||||
.gdscr = 0xf004,
|
||||
.pd = {
|
||||
.name = "usb30",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie0_gdsc = {
|
||||
.gdscr = 0x6b004,
|
||||
.pd = {
|
||||
.name = "pcie0",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie1_gdsc = {
|
||||
.gdscr = 0x6d004,
|
||||
.pd = {
|
||||
.name = "pcie1",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie2_gdsc = {
|
||||
.gdscr = 0x6e004,
|
||||
.pd = {
|
||||
.name = "pcie2",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc ufs_gdsc = {
|
||||
.gdscr = 0x75004,
|
||||
.pd = {
|
||||
.name = "ufs",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gcc_msm8996_clocks[] = {
|
||||
[GPLL0_EARLY] = &gpll0_early.clkr,
|
||||
[GPLL0] = &gpll0.clkr,
|
||||
@ -3245,6 +3321,18 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
|
||||
[GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gcc_msm8996_gdscs[] = {
|
||||
[AGGRE0_NOC_GDSC] = &aggre0_noc_gdsc,
|
||||
[HLOS1_VOTE_AGGRE0_NOC_GDSC] = &hlos1_vote_aggre0_noc_gdsc,
|
||||
[HLOS1_VOTE_LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp_gdsc,
|
||||
[HLOS1_VOTE_LPASS_CORE_GDSC] = &hlos1_vote_lpass_core_gdsc,
|
||||
[USB30_GDSC] = &usb30_gdsc,
|
||||
[PCIE0_GDSC] = &pcie0_gdsc,
|
||||
[PCIE1_GDSC] = &pcie1_gdsc,
|
||||
[PCIE2_GDSC] = &pcie2_gdsc,
|
||||
[UFS_GDSC] = &ufs_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_msm8996_resets[] = {
|
||||
[GCC_SYSTEM_NOC_BCR] = { 0x4000 },
|
||||
[GCC_CONFIG_NOC_BCR] = { 0x5000 },
|
||||
@ -3363,6 +3451,8 @@ static const struct qcom_cc_desc gcc_msm8996_desc = {
|
||||
.num_clks = ARRAY_SIZE(gcc_msm8996_clocks),
|
||||
.resets = gcc_msm8996_resets,
|
||||
.num_resets = ARRAY_SIZE(gcc_msm8996_resets),
|
||||
.gdscs = gcc_msm8996_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(gcc_msm8996_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id gcc_msm8996_match_table[] = {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset-controller.h>
|
||||
@ -42,12 +43,12 @@
|
||||
|
||||
#define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
|
||||
|
||||
static int gdsc_is_enabled(struct gdsc *sc)
|
||||
static int gdsc_is_enabled(struct gdsc *sc, unsigned int reg)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(sc->regmap, sc->gdscr, &val);
|
||||
ret = regmap_read(sc->regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -58,28 +59,46 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
|
||||
{
|
||||
int ret;
|
||||
u32 val = en ? 0 : SW_COLLAPSE_MASK;
|
||||
u32 check = en ? PWR_ON_MASK : 0;
|
||||
unsigned long timeout;
|
||||
ktime_t start;
|
||||
unsigned int status_reg = sc->gdscr;
|
||||
|
||||
ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
|
||||
/* If disabling votable gdscs, don't poll on status */
|
||||
if ((sc->flags & VOTABLE) && !en) {
|
||||
/*
|
||||
* Add a short delay here to ensure that an enable
|
||||
* right after it was disabled does not put it in an
|
||||
* unknown state
|
||||
*/
|
||||
udelay(TIMEOUT_US);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sc->gds_hw_ctrl) {
|
||||
status_reg = sc->gds_hw_ctrl;
|
||||
/*
|
||||
* The gds hw controller asserts/de-asserts the status bit soon
|
||||
* after it receives a power on/off request from a master.
|
||||
* The controller then takes around 8 xo cycles to start its
|
||||
* internal state machine and update the status bit. During
|
||||
* this time, the status bit does not reflect the true status
|
||||
* of the core.
|
||||
* Add a delay of 1 us between writing to the SW_COLLAPSE bit
|
||||
* and polling the status bit.
|
||||
*/
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
start = ktime_get();
|
||||
do {
|
||||
ret = regmap_read(sc->regmap, sc->gdscr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((val & PWR_ON_MASK) == check)
|
||||
if (gdsc_is_enabled(sc, status_reg) == en)
|
||||
return 0;
|
||||
} while (time_before(jiffies, timeout));
|
||||
} while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US);
|
||||
|
||||
ret = regmap_read(sc->regmap, sc->gdscr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((val & PWR_ON_MASK) == check)
|
||||
if (gdsc_is_enabled(sc, status_reg) == en)
|
||||
return 0;
|
||||
|
||||
return -ETIMEDOUT;
|
||||
@ -165,6 +184,7 @@ static int gdsc_init(struct gdsc *sc)
|
||||
{
|
||||
u32 mask, val;
|
||||
int on, ret;
|
||||
unsigned int reg;
|
||||
|
||||
/*
|
||||
* Disable HW trigger: collapse/restore occur based on registers writes.
|
||||
@ -185,10 +205,18 @@ static int gdsc_init(struct gdsc *sc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
on = gdsc_is_enabled(sc);
|
||||
reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
|
||||
on = gdsc_is_enabled(sc, reg);
|
||||
if (on < 0)
|
||||
return on;
|
||||
|
||||
/*
|
||||
* Votable GDSCs can be ON due to Vote from other masters.
|
||||
* If a Votable GDSC is ON, make sure we have a Vote.
|
||||
*/
|
||||
if ((sc->flags & VOTABLE) && on)
|
||||
gdsc_enable(&sc->pd);
|
||||
|
||||
if (on || (sc->pwrsts & PWRSTS_RET))
|
||||
gdsc_force_mem_on(sc);
|
||||
else
|
||||
@ -201,11 +229,14 @@ static int gdsc_init(struct gdsc *sc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
|
||||
int gdsc_register(struct gdsc_desc *desc,
|
||||
struct reset_controller_dev *rcdev, struct regmap *regmap)
|
||||
{
|
||||
int i, ret;
|
||||
struct genpd_onecell_data *data;
|
||||
struct device *dev = desc->dev;
|
||||
struct gdsc **scs = desc->scs;
|
||||
size_t num = desc->num;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
@ -228,10 +259,30 @@ int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
|
||||
data->domains[i] = &scs[i]->pd;
|
||||
}
|
||||
|
||||
/* Add subdomains */
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!scs[i])
|
||||
continue;
|
||||
if (scs[i]->parent)
|
||||
pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
|
||||
}
|
||||
|
||||
return of_genpd_add_provider_onecell(dev->of_node, data);
|
||||
}
|
||||
|
||||
void gdsc_unregister(struct device *dev)
|
||||
void gdsc_unregister(struct gdsc_desc *desc)
|
||||
{
|
||||
int i;
|
||||
struct device *dev = desc->dev;
|
||||
struct gdsc **scs = desc->scs;
|
||||
size_t num = desc->num;
|
||||
|
||||
/* Remove subdomains */
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!scs[i])
|
||||
continue;
|
||||
if (scs[i]->parent)
|
||||
pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
|
||||
}
|
||||
of_genpd_del_provider(dev->of_node);
|
||||
}
|
||||
|
@ -20,18 +20,12 @@
|
||||
struct regmap;
|
||||
struct reset_controller_dev;
|
||||
|
||||
/* Powerdomain allowable state bitfields */
|
||||
#define PWRSTS_OFF BIT(0)
|
||||
#define PWRSTS_RET BIT(1)
|
||||
#define PWRSTS_ON BIT(2)
|
||||
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
|
||||
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
||||
|
||||
/**
|
||||
* struct gdsc - Globally Distributed Switch Controller
|
||||
* @pd: generic power domain
|
||||
* @regmap: regmap for MMIO accesses
|
||||
* @gdscr: gsdc control register
|
||||
* @gds_hw_ctrl: gds_hw_ctrl register
|
||||
* @cxcs: offsets of branch registers to toggle mem/periph bits in
|
||||
* @cxc_count: number of @cxcs
|
||||
* @pwrsts: Possible powerdomain power states
|
||||
@ -41,28 +35,44 @@ struct reset_controller_dev;
|
||||
*/
|
||||
struct gdsc {
|
||||
struct generic_pm_domain pd;
|
||||
struct generic_pm_domain *parent;
|
||||
struct regmap *regmap;
|
||||
unsigned int gdscr;
|
||||
unsigned int gds_hw_ctrl;
|
||||
unsigned int *cxcs;
|
||||
unsigned int cxc_count;
|
||||
const u8 pwrsts;
|
||||
/* Powerdomain allowable state bitfields */
|
||||
#define PWRSTS_OFF BIT(0)
|
||||
#define PWRSTS_RET BIT(1)
|
||||
#define PWRSTS_ON BIT(2)
|
||||
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
|
||||
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
||||
const u8 flags;
|
||||
#define VOTABLE BIT(0)
|
||||
struct reset_controller_dev *rcdev;
|
||||
unsigned int *resets;
|
||||
unsigned int reset_count;
|
||||
};
|
||||
|
||||
struct gdsc_desc {
|
||||
struct device *dev;
|
||||
struct gdsc **scs;
|
||||
size_t num;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_QCOM_GDSC
|
||||
int gdsc_register(struct device *, struct gdsc **, size_t n,
|
||||
struct reset_controller_dev *, struct regmap *);
|
||||
void gdsc_unregister(struct device *);
|
||||
int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *,
|
||||
struct regmap *);
|
||||
void gdsc_unregister(struct gdsc_desc *desc);
|
||||
#else
|
||||
static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
|
||||
static inline int gdsc_register(struct gdsc_desc *desc,
|
||||
struct reset_controller_dev *rcdev,
|
||||
struct regmap *r)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline void gdsc_unregister(struct device *d) {};
|
||||
static inline void gdsc_unregister(struct gdsc_desc *desc) {};
|
||||
#endif /* CONFIG_QCOM_GDSC */
|
||||
#endif /* __QCOM_GDSC_H__ */
|
||||
|
@ -1789,7 +1789,6 @@ static struct clk_branch gmem_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gmem_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1805,7 +1804,6 @@ static struct clk_branch ijpeg_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ijpeg_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1821,7 +1819,6 @@ static struct clk_branch mmss_imem_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mmss_imem_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1835,7 +1832,6 @@ static struct clk_branch jpegd_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "jpegd_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1851,7 +1847,6 @@ static struct clk_branch vcodec_axi_b_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vcodec_axi_b_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1867,7 +1862,6 @@ static struct clk_branch vcodec_axi_a_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vcodec_axi_a_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1883,7 +1877,6 @@ static struct clk_branch vcodec_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vcodec_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1897,7 +1890,6 @@ static struct clk_branch vfe_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vfe_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1913,7 +1905,6 @@ static struct clk_branch mdp_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mdp_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1929,7 +1920,6 @@ static struct clk_branch rot_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "rot_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1945,7 +1935,6 @@ static struct clk_branch vcap_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vcap_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1961,7 +1950,6 @@ static struct clk_branch vpe_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vpe_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1977,7 +1965,6 @@ static struct clk_branch gfx3d_axi_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx3d_axi_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1991,7 +1978,6 @@ static struct clk_branch amp_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "amp_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2005,7 +1991,6 @@ static struct clk_branch csi_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "csi_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2019,7 +2004,6 @@ static struct clk_branch dsi_m_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi_m_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2035,7 +2019,6 @@ static struct clk_branch dsi_s_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi_s_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2049,7 +2032,6 @@ static struct clk_branch dsi2_m_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi2_m_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2065,7 +2047,6 @@ static struct clk_branch dsi2_s_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi2_s_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2425,7 +2406,6 @@ static struct clk_branch gfx2d0_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx2d0_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2441,7 +2421,6 @@ static struct clk_branch gfx2d1_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx2d1_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2457,7 +2436,6 @@ static struct clk_branch gfx3d_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx3d_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2473,7 +2451,6 @@ static struct clk_branch hdmi_m_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_m_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2489,7 +2466,6 @@ static struct clk_branch hdmi_s_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_s_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2503,7 +2479,6 @@ static struct clk_branch ijpeg_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ijpeg_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2519,7 +2494,6 @@ static struct clk_branch mmss_imem_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mmss_imem_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2533,7 +2507,6 @@ static struct clk_branch jpegd_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "jpegd_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2547,7 +2520,6 @@ static struct clk_branch mdp_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mdp_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2561,7 +2533,6 @@ static struct clk_branch rot_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "rot_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2577,7 +2548,6 @@ static struct clk_branch smmu_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "smmu_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2591,7 +2561,6 @@ static struct clk_branch tv_enc_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "tv_enc_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2605,7 +2574,6 @@ static struct clk_branch vcap_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vcap_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2621,7 +2589,6 @@ static struct clk_branch vcodec_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vcodec_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2635,7 +2602,6 @@ static struct clk_branch vfe_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vfe_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -2649,7 +2615,6 @@ static struct clk_branch vpe_ahb_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vpe_ahb_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -2400,6 +2400,7 @@ static struct gdsc oxilicx_gdsc = {
|
||||
.pd = {
|
||||
.name = "oxilicx",
|
||||
},
|
||||
.parent = &oxili_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
@ -2615,7 +2616,6 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table);
|
||||
static int mmcc_msm8974_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc);
|
||||
if (IS_ERR(regmap))
|
||||
@ -2624,22 +2624,11 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
|
||||
clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
|
||||
clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
|
||||
|
||||
ret = qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return pm_genpd_add_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd);
|
||||
}
|
||||
|
||||
static int mmcc_msm8974_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_genpd_remove_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd);
|
||||
return 0;
|
||||
return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver mmcc_msm8974_driver = {
|
||||
.probe = mmcc_msm8974_probe,
|
||||
.remove = mmcc_msm8974_remove,
|
||||
.driver = {
|
||||
.name = "mmcc-msm8974",
|
||||
.of_match_table = mmcc_msm8974_match_table,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
|
||||
|
||||
@ -2917,6 +2918,144 @@ static struct clk_hw *mmcc_msm8996_hws[] = {
|
||||
&gpll0_div.hw,
|
||||
};
|
||||
|
||||
static struct gdsc mmagic_video_gdsc = {
|
||||
.gdscr = 0x119c,
|
||||
.gds_hw_ctrl = 0x120c,
|
||||
.pd = {
|
||||
.name = "mmagic_video",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc mmagic_mdss_gdsc = {
|
||||
.gdscr = 0x247c,
|
||||
.gds_hw_ctrl = 0x2480,
|
||||
.pd = {
|
||||
.name = "mmagic_mdss",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc mmagic_camss_gdsc = {
|
||||
.gdscr = 0x3c4c,
|
||||
.gds_hw_ctrl = 0x3c50,
|
||||
.pd = {
|
||||
.name = "mmagic_camss",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc venus_gdsc = {
|
||||
.gdscr = 0x1024,
|
||||
.cxcs = (unsigned int []){ 0x1028, 0x1034, 0x1038 },
|
||||
.cxc_count = 3,
|
||||
.pd = {
|
||||
.name = "venus",
|
||||
},
|
||||
.parent = &mmagic_video_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc venus_core0_gdsc = {
|
||||
.gdscr = 0x1040,
|
||||
.cxcs = (unsigned int []){ 0x1048 },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "venus_core0",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc venus_core1_gdsc = {
|
||||
.gdscr = 0x1044,
|
||||
.cxcs = (unsigned int []){ 0x104c },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "venus_core1",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc camss_gdsc = {
|
||||
.gdscr = 0x34a0,
|
||||
.cxcs = (unsigned int []){ 0x36bc, 0x36c4 },
|
||||
.cxc_count = 2,
|
||||
.pd = {
|
||||
.name = "camss",
|
||||
},
|
||||
.parent = &mmagic_camss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc vfe0_gdsc = {
|
||||
.gdscr = 0x3664,
|
||||
.cxcs = (unsigned int []){ 0x36a8 },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "vfe0",
|
||||
},
|
||||
.parent = &camss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc vfe1_gdsc = {
|
||||
.gdscr = 0x3674,
|
||||
.cxcs = (unsigned int []){ 0x36ac },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "vfe0",
|
||||
},
|
||||
.parent = &camss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc jpeg_gdsc = {
|
||||
.gdscr = 0x35a4,
|
||||
.cxcs = (unsigned int []){ 0x35a8, 0x35b0, 0x35c0, 0x35b8 },
|
||||
.cxc_count = 4,
|
||||
.pd = {
|
||||
.name = "jpeg",
|
||||
},
|
||||
.parent = &camss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc cpp_gdsc = {
|
||||
.gdscr = 0x36d4,
|
||||
.cxcs = (unsigned int []){ 0x36b0 },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "cpp",
|
||||
},
|
||||
.parent = &camss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc fd_gdsc = {
|
||||
.gdscr = 0x3b64,
|
||||
.cxcs = (unsigned int []){ 0x3b68, 0x3b6c },
|
||||
.cxc_count = 2,
|
||||
.pd = {
|
||||
.name = "fd",
|
||||
},
|
||||
.parent = &camss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc mdss_gdsc = {
|
||||
.gdscr = 0x2304,
|
||||
.cxcs = (unsigned int []){ 0x2310, 0x231c },
|
||||
.cxc_count = 2,
|
||||
.pd = {
|
||||
.name = "mdss",
|
||||
},
|
||||
.parent = &mmagic_mdss_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *mmcc_msm8996_clocks[] = {
|
||||
[MMPLL0_EARLY] = &mmpll0_early.clkr,
|
||||
[MMPLL0_PLL] = &mmpll0.clkr,
|
||||
@ -3093,6 +3232,22 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = {
|
||||
[FD_AHB_CLK] = &fd_ahb_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *mmcc_msm8996_gdscs[] = {
|
||||
[MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc,
|
||||
[MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc,
|
||||
[MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc,
|
||||
[VENUS_GDSC] = &venus_gdsc,
|
||||
[VENUS_CORE0_GDSC] = &venus_core0_gdsc,
|
||||
[VENUS_CORE1_GDSC] = &venus_core1_gdsc,
|
||||
[CAMSS_GDSC] = &camss_gdsc,
|
||||
[VFE0_GDSC] = &vfe0_gdsc,
|
||||
[VFE1_GDSC] = &vfe1_gdsc,
|
||||
[JPEG_GDSC] = &jpeg_gdsc,
|
||||
[CPP_GDSC] = &cpp_gdsc,
|
||||
[FD_GDSC] = &fd_gdsc,
|
||||
[MDSS_GDSC] = &mdss_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map mmcc_msm8996_resets[] = {
|
||||
[MMAGICAHB_BCR] = { 0x5020 },
|
||||
[MMAGIC_CFG_BCR] = { 0x5050 },
|
||||
@ -3170,6 +3325,8 @@ static const struct qcom_cc_desc mmcc_msm8996_desc = {
|
||||
.num_clks = ARRAY_SIZE(mmcc_msm8996_clocks),
|
||||
.resets = mmcc_msm8996_resets,
|
||||
.num_resets = ARRAY_SIZE(mmcc_msm8996_resets),
|
||||
.gdscs = mmcc_msm8996_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(mmcc_msm8996_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id mmcc_msm8996_match_table[] = {
|
||||
|
@ -82,9 +82,8 @@ static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct div6_clock *clock = to_div6_clock(hw);
|
||||
unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
|
||||
|
||||
return parent_rate / div;
|
||||
return parent_rate / clock->div;
|
||||
}
|
||||
|
||||
static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
|
@ -1,5 +1,5 @@
|
||||
#ifndef __SHMOBILE_CLK_DIV6_H__
|
||||
#define __SHMOBILE_CLK_DIV6_H__
|
||||
#ifndef __RENESAS_CLK_DIV6_H__
|
||||
#define __RENESAS_CLK_DIV6_H__
|
||||
|
||||
struct clk *cpg_div6_register(const char *name, unsigned int num_parents,
|
||||
const char **parent_names, void __iomem *reg);
|
@ -14,7 +14,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/math64.h>
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/shmobile.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
@ -20,6 +20,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
|
||||
|
||||
@ -61,6 +62,7 @@ enum r8a7795_clk_types {
|
||||
CLK_TYPE_GEN3_PLL2,
|
||||
CLK_TYPE_GEN3_PLL3,
|
||||
CLK_TYPE_GEN3_PLL4,
|
||||
CLK_TYPE_GEN3_SD,
|
||||
};
|
||||
|
||||
static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
@ -99,11 +101,18 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1),
|
||||
DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074),
|
||||
DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078),
|
||||
DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268),
|
||||
DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c),
|
||||
|
||||
DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
|
||||
DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014),
|
||||
DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250),
|
||||
DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
@ -120,8 +129,17 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("scif2", 310, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("sdif3", 311, R8A7795_CLK_SD3),
|
||||
DEF_MOD("sdif2", 312, R8A7795_CLK_SD2),
|
||||
DEF_MOD("sdif1", 313, R8A7795_CLK_SD1),
|
||||
DEF_MOD("sdif0", 314, R8A7795_CLK_SD0),
|
||||
DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("intc-ex", 407, R8A7795_CLK_CP),
|
||||
DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4),
|
||||
@ -130,6 +148,21 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvd1", 602, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvd0", 603, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvb1", 606, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvb0", 607, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvi2", 609, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvi1", 610, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvi0", 611, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpf2", 613, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpf1", 614, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpf0", 615, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpci1", 616, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpci0", 617, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpcs", 619, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1),
|
||||
@ -147,6 +180,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("du2", 722, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du1", 723, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du0", 724, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("lvds", 727, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI),
|
||||
DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI),
|
||||
DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2),
|
||||
@ -159,6 +193,9 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("gpio2", 910, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio1", 911, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio0", 912, R8A7795_CLK_CP),
|
||||
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("i2c4", 927, R8A7795_CLK_S3D2),
|
||||
@ -198,6 +235,221 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
|
||||
MOD_CLK_ID(408), /* INTC-AP (GIC) */
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SDn Clock
|
||||
*
|
||||
*/
|
||||
#define CPG_SD_STP_HCK BIT(9)
|
||||
#define CPG_SD_STP_CK BIT(8)
|
||||
|
||||
#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
|
||||
#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
|
||||
|
||||
#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
|
||||
{ \
|
||||
.val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
|
||||
((stp_ck) ? CPG_SD_STP_CK : 0) | \
|
||||
((sd_srcfc) << 2) | \
|
||||
((sd_fc) << 0), \
|
||||
.div = (sd_div), \
|
||||
}
|
||||
|
||||
struct sd_div_table {
|
||||
u32 val;
|
||||
unsigned int div;
|
||||
};
|
||||
|
||||
struct sd_clock {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
const struct sd_div_table *div_table;
|
||||
unsigned int div_num;
|
||||
unsigned int div_min;
|
||||
unsigned int div_max;
|
||||
};
|
||||
|
||||
/* SDn divider
|
||||
* sd_srcfc sd_fc div
|
||||
* stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc
|
||||
*-------------------------------------------------------------------
|
||||
* 0 0 0 (1) 1 (4) 4
|
||||
* 0 0 1 (2) 1 (4) 8
|
||||
* 1 0 2 (4) 1 (4) 16
|
||||
* 1 0 3 (8) 1 (4) 32
|
||||
* 1 0 4 (16) 1 (4) 64
|
||||
* 0 0 0 (1) 0 (2) 2
|
||||
* 0 0 1 (2) 0 (2) 4
|
||||
* 1 0 2 (4) 0 (2) 8
|
||||
* 1 0 3 (8) 0 (2) 16
|
||||
* 1 0 4 (16) 0 (2) 32
|
||||
*/
|
||||
static const struct sd_div_table cpg_sd_div_table[] = {
|
||||
/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32),
|
||||
};
|
||||
|
||||
#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw)
|
||||
|
||||
static int cpg_sd_clock_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
u32 val, sd_fc;
|
||||
unsigned int i;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
|
||||
sd_fc = val & CPG_SD_FC_MASK;
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
val &= ~(CPG_SD_STP_MASK);
|
||||
val |= clock->div_table[i].val & CPG_SD_STP_MASK;
|
||||
|
||||
clk_writel(val, clock->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpg_sd_clock_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
return !(clk_readl(clock->reg) & CPG_SD_STP_MASK);
|
||||
}
|
||||
|
||||
static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned long rate = parent_rate;
|
||||
u32 val, sd_fc;
|
||||
unsigned int i;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
|
||||
sd_fc = val & CPG_SD_FC_MASK;
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div);
|
||||
}
|
||||
|
||||
static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
unsigned int div;
|
||||
|
||||
if (!rate)
|
||||
rate = 1;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
|
||||
return clamp_t(unsigned int, div, clock->div_min, clock->div_max);
|
||||
}
|
||||
|
||||
static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate);
|
||||
|
||||
return DIV_ROUND_CLOSEST(*parent_rate, div);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
|
||||
u32 val;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (div == clock->div_table[i].div)
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
|
||||
val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
|
||||
clk_writel(val, clock->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops cpg_sd_clock_ops = {
|
||||
.enable = cpg_sd_clock_enable,
|
||||
.disable = cpg_sd_clock_disable,
|
||||
.is_enabled = cpg_sd_clock_is_enabled,
|
||||
.recalc_rate = cpg_sd_clock_recalc_rate,
|
||||
.round_rate = cpg_sd_clock_round_rate,
|
||||
.set_rate = cpg_sd_clock_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
|
||||
void __iomem *base,
|
||||
const char *parent_name)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct sd_clock *clock;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = core->name;
|
||||
init.ops = &cpg_sd_clock_ops;
|
||||
init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
clock->reg = base + core->offset;
|
||||
clock->hw.init = &init;
|
||||
clock->div_table = cpg_sd_div_table;
|
||||
clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
|
||||
|
||||
clock->div_max = clock->div_table[0].div;
|
||||
clock->div_min = clock->div_max;
|
||||
for (i = 1; i < clock->div_num; i++) {
|
||||
clock->div_max = max(clock->div_max, clock->div_table[i].div);
|
||||
clock->div_min = min(clock->div_min, clock->div_table[i].div);
|
||||
}
|
||||
|
||||
clk = clk_register(NULL, &clock->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(clock);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
#define CPG_PLL0CR 0x00d8
|
||||
#define CPG_PLL2CR 0x002c
|
||||
@ -323,6 +575,9 @@ struct clk * __init r8a7795_cpg_clk_register(struct device *dev,
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_SD:
|
||||
return cpg_sd_clk_register(core, base, __clk_get_name(parent));
|
||||
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user