Commit 280da705 authored by Michael Turquette's avatar Michael Turquette

Merge branch 'clk-next-mmp' into clk-next

parents baeb0d9b d41ef540
* Marvell MMP2 Clock Controller
The MMP2 clock subsystem generates and supplies clock to various
controllers within the MMP2 SoC.
Required Properties:
- compatible: should be one of the following.
- "marvell,mmp2-clock" - controller compatible with MMP2 SoC.
- reg: physical base address of the clock subsystem and length of memory mapped
region. There are 3 places in SOC has clock control logic:
"mpmu", "apmu", "apbc". So three reg spaces need to be defined.
- #clock-cells: should be 1.
- #reset-cells: should be 1.
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/marvell-mmp2.h>.
* Marvell PXA168 Clock Controller
The PXA168 clock subsystem generates and supplies clock to various
controllers within the PXA168 SoC.
Required Properties:
- compatible: should be one of the following.
- "marvell,pxa168-clock" - controller compatible with PXA168 SoC.
- reg: physical base address of the clock subsystem and length of memory mapped
region. There are 3 places in SOC has clock control logic:
"mpmu", "apmu", "apbc". So three reg spaces need to be defined.
- #clock-cells: should be 1.
- #reset-cells: should be 1.
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/marvell,pxa168.h>.
* Marvell PXA910 Clock Controller
The PXA910 clock subsystem generates and supplies clock to various
controllers within the PXA910 SoC.
Required Properties:
- compatible: should be one of the following.
- "marvell,pxa910-clock" - controller compatible with PXA910 SoC.
- reg: physical base address of the clock subsystem and length of memory mapped
region. There are 4 places in SOC has clock control logic:
"mpmu", "apmu", "apbc", "apbcp". So four reg spaces need to be defined.
- #clock-cells: should be 1.
- #reset-cells: should be 1.
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/marvell-pxa910.h>.
...@@ -164,6 +164,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \ ...@@ -164,6 +164,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
pxa910-dkb.dtb \
mmp2-brownstone.dtb
dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
dtb-$(CONFIG_ARCH_MXC) += \ dtb-$(CONFIG_ARCH_MXC) += \
imx1-ads.dtb \ imx1-ads.dtb \
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
*/ */
/dts-v1/; /dts-v1/;
/include/ "mmp2.dtsi" #include "mmp2.dtsi"
/ { / {
model = "Marvell MMP2 Brownstone Development Board"; model = "Marvell MMP2 Brownstone Development Board";
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
* publishhed by the Free Software Foundation. * publishhed by the Free Software Foundation.
*/ */
/include/ "skeleton.dtsi" #include "skeleton.dtsi"
#include <dt-bindings/clock/marvell,mmp2.h>
/ { / {
aliases { aliases {
...@@ -135,6 +136,8 @@ uart1: uart@d4030000 { ...@@ -135,6 +136,8 @@ uart1: uart@d4030000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4030000 0x1000>; reg = <0xd4030000 0x1000>;
interrupts = <27>; interrupts = <27>;
clocks = <&soc_clocks MMP2_CLK_UART0>;
resets = <&soc_clocks MMP2_CLK_UART0>;
status = "disabled"; status = "disabled";
}; };
...@@ -142,6 +145,8 @@ uart2: uart@d4017000 { ...@@ -142,6 +145,8 @@ uart2: uart@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
interrupts = <28>; interrupts = <28>;
clocks = <&soc_clocks MMP2_CLK_UART1>;
resets = <&soc_clocks MMP2_CLK_UART1>;
status = "disabled"; status = "disabled";
}; };
...@@ -149,6 +154,8 @@ uart3: uart@d4018000 { ...@@ -149,6 +154,8 @@ uart3: uart@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
interrupts = <24>; interrupts = <24>;
clocks = <&soc_clocks MMP2_CLK_UART2>;
resets = <&soc_clocks MMP2_CLK_UART2>;
status = "disabled"; status = "disabled";
}; };
...@@ -156,6 +163,8 @@ uart4: uart@d4016000 { ...@@ -156,6 +163,8 @@ uart4: uart@d4016000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4016000 0x1000>; reg = <0xd4016000 0x1000>;
interrupts = <46>; interrupts = <46>;
clocks = <&soc_clocks MMP2_CLK_UART3>;
resets = <&soc_clocks MMP2_CLK_UART3>;
status = "disabled"; status = "disabled";
}; };
...@@ -168,6 +177,8 @@ gpio@d4019000 { ...@@ -168,6 +177,8 @@ gpio@d4019000 {
#gpio-cells = <2>; #gpio-cells = <2>;
interrupts = <49>; interrupts = <49>;
interrupt-names = "gpio_mux"; interrupt-names = "gpio_mux";
clocks = <&soc_clocks MMP2_CLK_GPIO>;
resets = <&soc_clocks MMP2_CLK_GPIO>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
ranges; ranges;
...@@ -201,6 +212,8 @@ twsi1: i2c@d4011000 { ...@@ -201,6 +212,8 @@ twsi1: i2c@d4011000 {
compatible = "mrvl,mmp-twsi"; compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>; reg = <0xd4011000 0x1000>;
interrupts = <7>; interrupts = <7>;
clocks = <&soc_clocks MMP2_CLK_TWSI0>;
resets = <&soc_clocks MMP2_CLK_TWSI0>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
mrvl,i2c-fast-mode; mrvl,i2c-fast-mode;
...@@ -211,6 +224,8 @@ twsi2: i2c@d4025000 { ...@@ -211,6 +224,8 @@ twsi2: i2c@d4025000 {
compatible = "mrvl,mmp-twsi"; compatible = "mrvl,mmp-twsi";
reg = <0xd4025000 0x1000>; reg = <0xd4025000 0x1000>;
interrupts = <58>; interrupts = <58>;
clocks = <&soc_clocks MMP2_CLK_TWSI1>;
resets = <&soc_clocks MMP2_CLK_TWSI1>;
status = "disabled"; status = "disabled";
}; };
...@@ -220,8 +235,20 @@ rtc: rtc@d4010000 { ...@@ -220,8 +235,20 @@ rtc: rtc@d4010000 {
interrupts = <1 0>; interrupts = <1 0>;
interrupt-names = "rtc 1Hz", "rtc alarm"; interrupt-names = "rtc 1Hz", "rtc alarm";
interrupt-parent = <&intcmux5>; interrupt-parent = <&intcmux5>;
clocks = <&soc_clocks MMP2_CLK_RTC>;
resets = <&soc_clocks MMP2_CLK_RTC>;
status = "disabled"; status = "disabled";
}; };
}; };
soc_clocks: clocks{
compatible = "marvell,mmp2-clock";
reg = <0xd4050000 0x1000>,
<0xd4282800 0x400>,
<0xd4015000 0x1000>;
reg-names = "mpmu", "apmu", "apbc";
#clock-cells = <1>;
#reset-cells = <1>;
};
}; };
}; };
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
*/ */
/dts-v1/; /dts-v1/;
/include/ "pxa168.dtsi" #include "pxa168.dtsi"
/ { / {
model = "Marvell PXA168 Aspenite Development Board"; model = "Marvell PXA168 Aspenite Development Board";
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
* publishhed by the Free Software Foundation. * publishhed by the Free Software Foundation.
*/ */
/include/ "skeleton.dtsi" #include "skeleton.dtsi"
#include <dt-bindings/clock/marvell,pxa168.h>
/ { / {
aliases { aliases {
...@@ -59,6 +60,8 @@ uart1: uart@d4017000 { ...@@ -59,6 +60,8 @@ uart1: uart@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
interrupts = <27>; interrupts = <27>;
clocks = <&soc_clocks PXA168_CLK_UART0>;
resets = <&soc_clocks PXA168_CLK_UART0>;
status = "disabled"; status = "disabled";
}; };
...@@ -66,6 +69,8 @@ uart2: uart@d4018000 { ...@@ -66,6 +69,8 @@ uart2: uart@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
interrupts = <28>; interrupts = <28>;
clocks = <&soc_clocks PXA168_CLK_UART1>;
resets = <&soc_clocks PXA168_CLK_UART1>;
status = "disabled"; status = "disabled";
}; };
...@@ -73,6 +78,8 @@ uart3: uart@d4026000 { ...@@ -73,6 +78,8 @@ uart3: uart@d4026000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4026000 0x1000>; reg = <0xd4026000 0x1000>;
interrupts = <29>; interrupts = <29>;
clocks = <&soc_clocks PXA168_CLK_UART2>;
resets = <&soc_clocks PXA168_CLK_UART2>;
status = "disabled"; status = "disabled";
}; };
...@@ -84,6 +91,8 @@ gpio@d4019000 { ...@@ -84,6 +91,8 @@ gpio@d4019000 {
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
interrupts = <49>; interrupts = <49>;
clocks = <&soc_clocks PXA168_CLK_GPIO>;
resets = <&soc_clocks PXA168_CLK_GPIO>;
interrupt-names = "gpio_mux"; interrupt-names = "gpio_mux";
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
...@@ -110,6 +119,8 @@ twsi1: i2c@d4011000 { ...@@ -110,6 +119,8 @@ twsi1: i2c@d4011000 {
compatible = "mrvl,mmp-twsi"; compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>; reg = <0xd4011000 0x1000>;
interrupts = <7>; interrupts = <7>;
clocks = <&soc_clocks PXA168_CLK_TWSI0>;
resets = <&soc_clocks PXA168_CLK_TWSI0>;
mrvl,i2c-fast-mode; mrvl,i2c-fast-mode;
status = "disabled"; status = "disabled";
}; };
...@@ -118,6 +129,8 @@ twsi2: i2c@d4025000 { ...@@ -118,6 +129,8 @@ twsi2: i2c@d4025000 {
compatible = "mrvl,mmp-twsi"; compatible = "mrvl,mmp-twsi";
reg = <0xd4025000 0x1000>; reg = <0xd4025000 0x1000>;
interrupts = <58>; interrupts = <58>;
clocks = <&soc_clocks PXA168_CLK_TWSI1>;
resets = <&soc_clocks PXA168_CLK_TWSI1>;
status = "disabled"; status = "disabled";
}; };
...@@ -126,8 +139,20 @@ rtc: rtc@d4010000 { ...@@ -126,8 +139,20 @@ rtc: rtc@d4010000 {
reg = <0xd4010000 0x1000>; reg = <0xd4010000 0x1000>;
interrupts = <5 6>; interrupts = <5 6>;
interrupt-names = "rtc 1Hz", "rtc alarm"; interrupt-names = "rtc 1Hz", "rtc alarm";
clocks = <&soc_clocks PXA168_CLK_RTC>;
resets = <&soc_clocks PXA168_CLK_RTC>;
status = "disabled"; status = "disabled";
}; };
}; };
soc_clocks: clocks{
compatible = "marvell,pxa168-clock";
reg = <0xd4050000 0x1000>,
<0xd4282800 0x400>,
<0xd4015000 0x1000>;
reg-names = "mpmu", "apmu", "apbc";
#clock-cells = <1>;
#reset-cells = <1>;
};
}; };
}; };
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
*/ */
/dts-v1/; /dts-v1/;
/include/ "pxa910.dtsi" #include "pxa910.dtsi"
/ { / {
model = "Marvell PXA910 DKB Development Board"; model = "Marvell PXA910 DKB Development Board";
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
* publishhed by the Free Software Foundation. * publishhed by the Free Software Foundation.
*/ */
/include/ "skeleton.dtsi" #include "skeleton.dtsi"
#include <dt-bindings/clock/marvell,pxa910.h>
/ { / {
aliases { aliases {
...@@ -71,6 +72,8 @@ uart1: uart@d4017000 { ...@@ -71,6 +72,8 @@ uart1: uart@d4017000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4017000 0x1000>; reg = <0xd4017000 0x1000>;
interrupts = <27>; interrupts = <27>;
clocks = <&soc_clocks PXA910_CLK_UART0>;
resets = <&soc_clocks PXA910_CLK_UART0>;
status = "disabled"; status = "disabled";
}; };
...@@ -78,6 +81,8 @@ uart2: uart@d4018000 { ...@@ -78,6 +81,8 @@ uart2: uart@d4018000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4018000 0x1000>; reg = <0xd4018000 0x1000>;
interrupts = <28>; interrupts = <28>;
clocks = <&soc_clocks PXA910_CLK_UART1>;
resets = <&soc_clocks PXA910_CLK_UART1>;
status = "disabled"; status = "disabled";
}; };
...@@ -85,6 +90,8 @@ uart3: uart@d4036000 { ...@@ -85,6 +90,8 @@ uart3: uart@d4036000 {
compatible = "mrvl,mmp-uart"; compatible = "mrvl,mmp-uart";
reg = <0xd4036000 0x1000>; reg = <0xd4036000 0x1000>;
interrupts = <59>; interrupts = <59>;
clocks = <&soc_clocks PXA910_CLK_UART2>;
resets = <&soc_clocks PXA910_CLK_UART2>;
status = "disabled"; status = "disabled";
}; };
...@@ -97,6 +104,8 @@ gpio@d4019000 { ...@@ -97,6 +104,8 @@ gpio@d4019000 {
#gpio-cells = <2>; #gpio-cells = <2>;
interrupts = <49>; interrupts = <49>;
interrupt-names = "gpio_mux"; interrupt-names = "gpio_mux";
clocks = <&soc_clocks PXA910_CLK_GPIO>;
resets = <&soc_clocks PXA910_CLK_GPIO>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
ranges; ranges;
...@@ -124,6 +133,8 @@ twsi1: i2c@d4011000 { ...@@ -124,6 +133,8 @@ twsi1: i2c@d4011000 {
#size-cells = <0>; #size-cells = <0>;
reg = <0xd4011000 0x1000>; reg = <0xd4011000 0x1000>;
interrupts = <7>; interrupts = <7>;
clocks = <&soc_clocks PXA910_CLK_TWSI0>;
resets = <&soc_clocks PXA910_CLK_TWSI0>;
mrvl,i2c-fast-mode; mrvl,i2c-fast-mode;
status = "disabled"; status = "disabled";
}; };
...@@ -134,6 +145,8 @@ twsi2: i2c@d4037000 { ...@@ -134,6 +145,8 @@ twsi2: i2c@d4037000 {
#size-cells = <0>; #size-cells = <0>;
reg = <0xd4037000 0x1000>; reg = <0xd4037000 0x1000>;
interrupts = <54>; interrupts = <54>;
clocks = <&soc_clocks PXA910_CLK_TWSI1>;
resets = <&soc_clocks PXA910_CLK_TWSI1>;
status = "disabled"; status = "disabled";
}; };
...@@ -142,8 +155,21 @@ rtc: rtc@d4010000 { ...@@ -142,8 +155,21 @@ rtc: rtc@d4010000 {
reg = <0xd4010000 0x1000>; reg = <0xd4010000 0x1000>;
interrupts = <5 6>; interrupts = <5 6>;
interrupt-names = "rtc 1Hz", "rtc alarm"; interrupt-names = "rtc 1Hz", "rtc alarm";
clocks = <&soc_clocks PXA910_CLK_RTC>;
resets = <&soc_clocks PXA910_CLK_RTC>;
status = "disabled"; status = "disabled";
}; };
}; };
soc_clocks: clocks{
compatible = "marvell,pxa910-clock";
reg = <0xd4050000 0x1000>,
<0xd4282800 0x400>,
<0xd4015000 0x1000>,
<0xd403b000 0x1000>;
reg-names = "mpmu", "apmu", "apbc", "apbcp";
#clock-cells = <1>;
#reset-cells = <1>;
};
}; };
}; };
...@@ -86,11 +86,12 @@ config MACH_GPLUGD ...@@ -86,11 +86,12 @@ config MACH_GPLUGD
config MACH_MMP_DT config MACH_MMP_DT
bool "Support MMP (ARMv5) platforms from device tree" bool "Support MMP (ARMv5) platforms from device tree"
select CPU_PXA168
select CPU_PXA910
select USE_OF select USE_OF
select PINCTRL select PINCTRL
select PINCTRL_SINGLE select PINCTRL_SINGLE
select COMMON_CLK
select ARCH_HAS_RESET_CONTROLLER
select CPU_MOHAWK
help help
Include support for Marvell MMP2 based platforms using Include support for Marvell MMP2 based platforms using
the device tree. Needn't select any other machine while the device tree. Needn't select any other machine while
...@@ -99,10 +100,12 @@ config MACH_MMP_DT ...@@ -99,10 +100,12 @@ config MACH_MMP_DT
config MACH_MMP2_DT config MACH_MMP2_DT
bool "Support MMP2 (ARMv7) platforms from device tree" bool "Support MMP2 (ARMv7) platforms from device tree"
depends on !CPU_MOHAWK depends on !CPU_MOHAWK
select CPU_MMP2
select USE_OF select USE_OF
select PINCTRL select PINCTRL
select PINCTRL_SINGLE select PINCTRL_SINGLE
select COMMON_CLK
select ARCH_HAS_RESET_CONTROLLER
select CPU_PJ4
help help
Include support for Marvell MMP2 based platforms using Include support for Marvell MMP2 based platforms using
the device tree. the device tree.
...@@ -111,21 +114,18 @@ endmenu ...@@ -111,21 +114,18 @@ endmenu
config CPU_PXA168 config CPU_PXA168
bool bool
select COMMON_CLK
select CPU_MOHAWK select CPU_MOHAWK
help help
Select code specific to PXA168 Select code specific to PXA168
config CPU_PXA910 config CPU_PXA910
bool bool
select COMMON_CLK
select CPU_MOHAWK select CPU_MOHAWK
help help
Select code specific to PXA910 Select code specific to PXA910
config CPU_MMP2 config CPU_MMP2
bool bool
select COMMON_CLK
select CPU_PJ4 select CPU_PJ4
help help
Select code specific to MMP2. MMP2 is ARMv7 compatible. Select code specific to MMP2. MMP2 is ARMv7 compatible.
......
...@@ -11,63 +11,42 @@ ...@@ -11,63 +11,42 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/hardware/cache-tauros2.h>
#include "common.h" #include "common.h"
extern void __init mmp_dt_init_timer(void); extern void __init mmp_dt_init_timer(void);
static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = { static const char *pxa168_dt_board_compat[] __initdata = {
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), "mrvl,pxa168-aspenite",
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), NULL,
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL),
OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp-gpio", NULL),
OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
{}
}; };
static const struct of_dev_auxdata pxa910_auxdata_lookup[] __initconst = { static const char *pxa910_dt_board_compat[] __initdata = {
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), "mrvl,pxa910-dkb",
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), NULL,
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL),
OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL),
OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp-gpio", NULL),
OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
{}
}; };
static void __init pxa168_dt_init(void) static void __init mmp_init_time(void)
{
of_platform_populate(NULL, of_default_bus_match_table,
pxa168_auxdata_lookup, NULL);
}
static void __init pxa910_dt_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, #ifdef CONFIG_CACHE_TAUROS2
pxa910_auxdata_lookup, NULL); tauros2_init(0);
#endif
mmp_dt_init_timer();
of_clk_init(NULL);
} }
static const char *mmp_dt_board_compat[] __initdata = {
"mrvl,pxa168-aspenite",
"mrvl,pxa910-dkb",
NULL,
};
DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)") DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
.map_io = mmp_map_io, .map_io = mmp_map_io,
.init_time = mmp_dt_init_timer, .init_time = mmp_init_time,
.init_machine = pxa168_dt_init, .dt_compat = pxa168_dt_board_compat,
.dt_compat = mmp_dt_board_compat,
MACHINE_END MACHINE_END
DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)") DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)")
.map_io = mmp_map_io, .map_io = mmp_map_io,
.init_time = mmp_dt_init_timer, .init_time = mmp_init_time,
.init_machine = pxa910_dt_init, .dt_compat = pxa910_dt_board_compat,
.dt_compat = mmp_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -12,29 +12,22 @@ ...@@ -12,29 +12,22 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/hardware/cache-tauros2.h>
#include "common.h" #include "common.h"
extern void __init mmp_dt_init_timer(void); extern void __init mmp_dt_init_timer(void);
static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = { static void __init mmp_init_time(void)
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000, "pxa2xx-uart.0", NULL),
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL),
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.2", NULL),
OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL),
OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp2-gpio", NULL),
OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
{}
};
static void __init mmp2_dt_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, #ifdef CONFIG_CACHE_TAUROS2
mmp2_auxdata_lookup, NULL); tauros2_init(0);
#endif
mmp_dt_init_timer();
of_clk_init(NULL);
} }
static const char *mmp2_dt_board_compat[] __initdata = { static const char *mmp2_dt_board_compat[] __initdata = {
...@@ -44,7 +37,6 @@ static const char *mmp2_dt_board_compat[] __initdata = { ...@@ -44,7 +37,6 @@ static const char *mmp2_dt_board_compat[] __initdata = {
DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)") DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
.map_io = mmp_map_io, .map_io = mmp_map_io,
.init_time = mmp_dt_init_timer, .init_time = mmp_init_time,
.init_machine = mmp2_dt_init,
.dt_compat = mmp2_dt_board_compat, .dt_compat = mmp2_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -2,7 +2,12 @@ ...@@ -2,7 +2,12 @@
# Makefile for mmp specific clk # Makefile for mmp specific clk
# #
obj-y += clk-apbc.o clk-apmu.o clk-frac.o obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
......
...@@ -22,19 +22,12 @@ ...@@ -22,19 +22,12 @@
* numerator/denominator = Fin / (Fout * factor) * numerator/denominator = Fin / (Fout * factor)
*/ */
#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw) #define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
struct clk_factor {
struct clk_hw hw;
void __iomem *base;
struct clk_factor_masks *masks;
struct clk_factor_tbl *ftbl;
unsigned int ftbl_cnt;
};
static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate) unsigned long *prate)
{ {
struct clk_factor *factor = to_clk_factor(hw); struct mmp_clk_factor *factor = to_clk_factor(hw);
unsigned long rate = 0, prev_rate; unsigned long rate = 0, prev_rate;
int i; int i;
...@@ -58,8 +51,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, ...@@ -58,8 +51,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
{ {
struct clk_factor *factor = to_clk_factor(hw); struct mmp_clk_factor *factor = to_clk_factor(hw);
struct clk_factor_masks *masks = factor->masks; struct mmp_clk_factor_masks *masks = factor->masks;
unsigned int val, num, den; unsigned int val, num, den;
val = readl_relaxed(factor->base); val = readl_relaxed(factor->base);
...@@ -81,11 +74,12 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, ...@@ -81,11 +74,12 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate) unsigned long prate)
{ {
struct clk_factor *factor = to_clk_factor(hw); struct mmp_clk_factor *factor = to_clk_factor(hw);
struct clk_factor_masks *masks = factor->masks; struct mmp_clk_factor_masks *masks = factor->masks;
int i; int i;
unsigned long val; unsigned long val;
unsigned long prev_rate, rate = 0; unsigned long prev_rate, rate = 0;
unsigned long flags = 0;
for (i = 0; i < factor->ftbl_cnt; i++) { for (i = 0; i < factor->ftbl_cnt; i++) {
prev_rate = rate; prev_rate = rate;
...@@ -97,6 +91,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, ...@@ -97,6 +91,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
if (i > 0) if (i > 0)
i--; i--;
if (factor->lock)
spin_lock_irqsave(factor->lock, flags);
val = readl_relaxed(factor->base); val = readl_relaxed(factor->base);
val &= ~(masks->num_mask << masks->num_shift); val &= ~(masks->num_mask << masks->num_shift);
...@@ -107,21 +104,65 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, ...@@ -107,21 +104,65 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
writel_relaxed(val, factor->base); writel_relaxed(val, factor->base);
if (factor->lock)
spin_unlock_irqrestore(factor->lock, flags);
return 0; return 0;
} }
void clk_factor_init(struct clk_hw *hw)
{
struct mmp_clk_factor *factor = to_clk_factor(hw);
struct mmp_clk_factor_masks *masks = factor->masks;
u32 val, num, den;
int i;
unsigned long flags = 0;
if (factor->lock)
spin_lock_irqsave(factor->lock, flags);
val = readl(factor->base);
/* calculate numerator */
num = (val >> masks->num_shift) & masks->num_mask;
/* calculate denominator */
den = (val >> masks->den_shift) & masks->den_mask;
for (i = 0; i < factor->ftbl_cnt; i++)
if (den == factor->ftbl[i].den && num == factor->ftbl[i].num)
break;
if (i >= factor->ftbl_cnt) {
val &= ~(masks->num_mask << masks->num_shift);
val |= (factor->ftbl[0].num & masks->num_mask) <<
masks->num_shift;
val &= ~(masks->den_mask << masks->den_shift);
val |= (factor->ftbl[0].den & masks->den_mask) <<
masks->den_shift;
writel(val, factor->base);
}
if (factor->lock)
spin_unlock_irqrestore(factor->lock, flags);
}
static struct clk_ops clk_factor_ops = { static struct clk_ops clk_factor_ops = {
.recalc_rate = clk_factor_recalc_rate, .recalc_rate = clk_factor_recalc_rate,
.round_rate = clk_factor_round_rate, .round_rate = clk_factor_round_rate,
.set_rate = clk_factor_set_rate, .set_rate = clk_factor_set_rate,
.init = clk_factor_init,
}; };
struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
unsigned long flags, void __iomem *base, unsigned long flags, void __iomem *base,
struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl, struct mmp_clk_factor_masks *masks,
unsigned int ftbl_cnt) struct mmp_clk_factor_tbl *ftbl,
unsigned int ftbl_cnt, spinlock_t *lock)
{ {
struct clk_factor *factor; struct mmp_clk_factor *factor;
struct clk_init_data init; struct clk_init_data init;
struct clk *clk; struct clk *clk;
...@@ -142,6 +183,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, ...@@ -142,6 +183,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
factor->ftbl = ftbl; factor->ftbl = ftbl;
factor->ftbl_cnt = ftbl_cnt; factor->ftbl_cnt = ftbl_cnt;
factor->hw.init = &init; factor->hw.init = &init;
factor->lock = lock;
init.name = name; init.name = name;
init.ops = &clk_factor_ops; init.ops = &clk_factor_ops;
......
/*
* mmp gate clock operation source file
*
* Copyright (C) 2014 Marvell
* Chao Xie <chao.xie@marvell.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/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/delay.h>
#include "clk.h"
/*
* Some clocks will have mutiple bits to enable the clocks, and
* the bits to disable the clock is not same as enabling bits.
*/
#define to_clk_mmp_gate(hw) container_of(hw, struct mmp_clk_gate, hw)
static int mmp_clk_gate_enable(struct clk_hw *hw)
{
struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
struct clk *clk = hw->clk;
unsigned long flags = 0;
unsigned long rate;
u32 tmp;
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
tmp = readl(gate->reg);
tmp &= ~gate->mask;
tmp |= gate->val_enable;
writel(tmp, gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
if (gate->flags & MMP_CLK_GATE_NEED_DELAY) {
rate = __clk_get_rate(clk);
/* Need delay 2 cycles. */
udelay(2000000/rate);
}
return 0;
}
static void mmp_clk_gate_disable(struct clk_hw *hw)
{
struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
unsigned long flags = 0;
u32 tmp;
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
tmp = readl(gate->reg);
tmp &= ~gate->mask;
tmp |= gate->val_disable;
writel(tmp, gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
}
static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
{
struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
unsigned long flags = 0;
u32 tmp;
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
tmp = readl(gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
return (tmp & gate->mask) == gate->val_enable;
}
const struct clk_ops mmp_clk_gate_ops = {
.enable = mmp_clk_gate_enable,
.disable = mmp_clk_gate_disable,
.is_enabled = mmp_clk_gate_is_enabled,
};
struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
unsigned int gate_flags, spinlock_t *lock)
{
struct mmp_clk_gate *gate;
struct clk *clk;
struct clk_init_data init;
/* allocate the gate */
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate) {
pr_err("%s:%s could not allocate gate clk\n", __func__, name);
return ERR_PTR(-ENOMEM);
}
init.name = name;
init.ops = &mmp_clk_gate_ops;
init.flags = flags | CLK_IS_BASIC;
init.parent_names = (parent_name ? &parent_name : NULL);
init.num_parents = (parent_name ? 1 : 0);
/* struct clk_gate assignments */
gate->reg = reg;
gate->mask = mask;
gate->val_enable = val_enable;
gate->val_disable = val_disable;
gate->flags = gate_flags;
gate->lock = lock;
gate->hw.init = &init;
clk = clk_register(dev, &gate->hw);
if (IS_ERR(clk))
kfree(gate);
return clk;
}
This diff is collapsed.
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
static DEFINE_SPINLOCK(clk_lock); static DEFINE_SPINLOCK(clk_lock);
static struct clk_factor_masks uart_factor_masks = { static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2, .factor = 2,
.num_mask = 0x1fff, .num_mask = 0x1fff,
.den_mask = 0x1fff, .den_mask = 0x1fff,
...@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = { ...@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0, .den_shift = 0,
}; };
static struct clk_factor_tbl uart_factor_tbl[] = { static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 14634, .den = 2165}, /*14.745MHZ */ {.num = 14634, .den = 2165}, /*14.745MHZ */
{.num = 3521, .den = 689}, /*19.23MHZ */ {.num = 3521, .den = 689}, /*19.23MHZ */
{.num = 9679, .den = 5728}, /*58.9824MHZ */ {.num = 9679, .den = 5728}, /*58.9824MHZ */
...@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void) ...@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0, clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL, mpmu_base + MPMU_UART_PLL,
&uart_factor_masks, uart_factor_tbl, &uart_factor_masks, uart_factor_tbl,
ARRAY_SIZE(uart_factor_tbl)); ARRAY_SIZE(uart_factor_tbl), &clk_lock);
clk_set_rate(clk, 14745600); clk_set_rate(clk, 14745600);
clk_register_clkdev(clk, "uart_pll", NULL); clk_register_clkdev(clk, "uart_pll", NULL);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
static DEFINE_SPINLOCK(clk_lock); static DEFINE_SPINLOCK(clk_lock);
static struct clk_factor_masks uart_factor_masks = { static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2, .factor = 2,
.num_mask = 0x1fff, .num_mask = 0x1fff,
.den_mask = 0x1fff, .den_mask = 0x1fff,
...@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = { ...@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0, .den_shift = 0,
}; };
static struct clk_factor_tbl uart_factor_tbl[] = { static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 8125, .den = 1536}, /*14.745MHZ */ {.num = 8125, .den = 1536}, /*14.745MHZ */
}; };
...@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void) ...@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL, mpmu_base + MPMU_UART_PLL,
&uart_factor_masks, uart_factor_tbl, &uart_factor_masks, uart_factor_tbl,
ARRAY_SIZE(uart_factor_tbl)); ARRAY_SIZE(uart_factor_tbl), &clk_lock);
clk_set_rate(uart_pll, 14745600); clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL); clk_register_clkdev(uart_pll, "uart_pll", NULL);
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
static DEFINE_SPINLOCK(clk_lock); static DEFINE_SPINLOCK(clk_lock);
static struct clk_factor_masks uart_factor_masks = { static struct mmp_clk_factor_masks uart_factor_masks = {
.factor = 2, .factor = 2,
.num_mask = 0x1fff, .num_mask = 0x1fff,
.den_mask = 0x1fff, .den_mask = 0x1fff,
...@@ -53,7 +53,7 @@ static struct clk_factor_masks uart_factor_masks = { ...@@ -53,7 +53,7 @@ static struct clk_factor_masks uart_factor_masks = {
.den_shift = 0, .den_shift = 0,
}; };
static struct clk_factor_tbl uart_factor_tbl[] = { static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 8125, .den = 1536}, /*14.745MHZ */ {.num = 8125, .den = 1536}, /*14.745MHZ */
}; };
...@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void) ...@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
mpmu_base + MPMU_UART_PLL, mpmu_base + MPMU_UART_PLL,
&uart_factor_masks, uart_factor_tbl, &uart_factor_masks, uart_factor_tbl,
ARRAY_SIZE(uart_factor_tbl)); ARRAY_SIZE(uart_factor_tbl), &clk_lock);
clk_set_rate(uart_pll, 14745600); clk_set_rate(uart_pll, 14745600);
clk_register_clkdev(uart_pll, "uart_pll", NULL); clk_register_clkdev(uart_pll, "uart_pll", NULL);
......
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include "clk.h"
void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
int nr_clks)
{
static struct clk **clk_table;
clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
if (!clk_table)
return;
unit->clk_table = clk_table;
unit->nr_clks = nr_clks;
unit->clk_data.clks = clk_table;
unit->clk_data.clk_num = nr_clks;
of_clk_add_provider(np, of_clk_src_onecell_get, &unit->clk_data);
}
void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
struct mmp_param_fixed_rate_clk *clks,
int size)
{
int i;
struct clk *clk;
for (i = 0; i < size; i++) {
clk = clk_register_fixed_rate(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
clks[i].fixed_rate);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].id)
unit->clk_table[clks[i].id] = clk;
}
}
void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
struct mmp_param_fixed_factor_clk *clks,
int size)
{
struct clk *clk;
int i;
for (i = 0; i < size; i++) {
clk = clk_register_fixed_factor(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags, clks[i].mult,
clks[i].div);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].id)
unit->clk_table[clks[i].id] = clk;
}
}
void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
struct mmp_param_general_gate_clk *clks,
void __iomem *base, int size)
{
struct clk *clk;
int i;
for (i = 0; i < size; i++) {
clk = clk_register_gate(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
base + clks[i].offset,
clks[i].bit_idx,
clks[i].gate_flags,
clks[i].lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].id)
unit->clk_table[clks[i].id] = clk;
}
}
void mmp_register_gate_clks(struct mmp_clk_unit *unit,
struct mmp_param_gate_clk *clks,
void __iomem *base, int size)
{
struct clk *clk;
int i;
for (i = 0; i < size; i++) {
clk = mmp_clk_register_gate(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
base + clks[i].offset,
clks[i].mask,
clks[i].val_enable,
clks[i].val_disable,
clks[i].gate_flags,
clks[i].lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].id)
unit->clk_table[clks[i].id] = clk;
}
}
void mmp_register_mux_clks(struct mmp_clk_unit *unit,
struct mmp_param_mux_clk *clks,
void __iomem *base, int size)
{
struct clk *clk;
int i;
for (i = 0; i < size; i++) {
clk = clk_register_mux(NULL, clks[i].name,
clks[i].parent_name,
clks[i].num_parents,
clks[i].flags,
base + clks[i].offset,
clks[i].shift,
clks[i].width,
clks[i].mux_flags,
clks[i].lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].id)
unit->clk_table[clks[i].id] = clk;
}
}
void mmp_register_div_clks(struct mmp_clk_unit *unit,
struct mmp_param_div_clk *clks,
void __iomem *base, int size)
{
struct clk *clk;
int i;
for (i = 0; i < size; i++) {
clk = clk_register_divider(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
base + clks[i].offset,
clks[i].shift,
clks[i].width,
clks[i].div_flags,
clks[i].lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].id)
unit->clk_table[clks[i].id] = clk;
}
}
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
struct clk *clk)
{
if (IS_ERR_OR_NULL(clk)) {
pr_err("CLK %d has invalid pointer %p\n", id, clk);
return;
}
if (id > unit->nr_clks) {
pr_err("CLK %d is invalid\n", id);
return;
}
unit->clk_table[id] = clk;
}
...@@ -7,19 +7,123 @@ ...@@ -7,19 +7,123 @@
#define APBC_NO_BUS_CTRL BIT(0) #define APBC_NO_BUS_CTRL BIT(0)
#define APBC_POWER_CTRL BIT(1) #define APBC_POWER_CTRL BIT(1)
struct clk_factor_masks {
unsigned int factor; /* Clock type "factor" */
unsigned int num_mask; struct mmp_clk_factor_masks {
unsigned int den_mask; unsigned int factor;
unsigned int num_shift; unsigned int num_mask;
unsigned int den_shift; unsigned int den_mask;
unsigned int num_shift;
unsigned int den_shift;
}; };
struct clk_factor_tbl { struct mmp_clk_factor_tbl {
unsigned int num; unsigned int num;
unsigned int den; unsigned int den;
}; };
struct mmp_clk_factor {
struct clk_hw hw;
void __iomem *base;
struct mmp_clk_factor_masks *masks;
struct mmp_clk_factor_tbl *ftbl;
unsigned int ftbl_cnt;
spinlock_t *lock;
};
extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags,
void __iomem *base, struct mmp_clk_factor_masks *masks,
struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
spinlock_t *lock);
/* Clock type "mix" */
#define MMP_CLK_BITS_MASK(width, shift) \
(((1 << (width)) - 1) << (shift))
#define MMP_CLK_BITS_GET_VAL(data, width, shift) \
((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))
#define MMP_CLK_BITS_SET_VAL(val, width, shift) \
(((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))
enum {
MMP_CLK_MIX_TYPE_V1,
MMP_CLK_MIX_TYPE_V2,
MMP_CLK_MIX_TYPE_V3,
};
/* The register layout */
struct mmp_clk_mix_reg_info {
void __iomem *reg_clk_ctrl;
void __iomem *reg_clk_sel;
u8 width_div;
u8 shift_div;
u8 width_mux;
u8 shift_mux;
u8 bit_fc;
};
/* The suggested clock table from user. */
struct mmp_clk_mix_clk_table {
unsigned long rate;
u8 parent_index;
unsigned int divisor;
unsigned int valid;
};
struct mmp_clk_mix_config {
struct mmp_clk_mix_reg_info reg_info;
struct mmp_clk_mix_clk_table *table;
unsigned int table_size;
u32 *mux_table;
struct clk_div_table *div_table;
u8 div_flags;
u8 mux_flags;
};
struct mmp_clk_mix {
struct clk_hw hw;
struct mmp_clk_mix_reg_info reg_info;
struct mmp_clk_mix_clk_table *table;
u32 *mux_table;
struct clk_div_table *div_table;
unsigned int table_size;
u8 div_flags;
u8 mux_flags;
unsigned int type;
spinlock_t *lock;
};
extern const struct clk_ops mmp_clk_mix_ops;
extern struct clk *mmp_clk_register_mix(struct device *dev,
const char *name,
const char **parent_names,
u8 num_parents,
unsigned long flags,
struct mmp_clk_mix_config *config,
spinlock_t *lock);
/* Clock type "gate". MMP private gate */
#define MMP_CLK_GATE_NEED_DELAY BIT(0)
struct mmp_clk_gate {
struct clk_hw hw;
void __iomem *reg;
u32 mask;
u32 val_enable;
u32 val_disable;
unsigned int flags;
spinlock_t *lock;
};
extern const struct clk_ops mmp_clk_gate_ops;
extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u32 mask, u32 val_enable,
u32 val_disable, unsigned int gate_flags,
spinlock_t *lock);
extern struct clk *mmp_clk_register_pll2(const char *name, extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags); const char *parent_name, unsigned long flags);
extern struct clk *mmp_clk_register_apbc(const char *name, extern struct clk *mmp_clk_register_apbc(const char *name,
...@@ -28,8 +132,108 @@ extern struct clk *mmp_clk_register_apbc(const char *name, ...@@ -28,8 +132,108 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
extern struct clk *mmp_clk_register_apmu(const char *name, extern struct clk *mmp_clk_register_apmu(const char *name,
const char *parent_name, void __iomem *base, u32 enable_mask, const char *parent_name, void __iomem *base, u32 enable_mask,
spinlock_t *lock); spinlock_t *lock);
extern struct clk *mmp_clk_register_factor(const char *name,
const char *parent_name, unsigned long flags, struct mmp_clk_unit {
void __iomem *base, struct clk_factor_masks *masks, unsigned int nr_clks;
struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt); struct clk **clk_table;
struct clk_onecell_data clk_data;
};
struct mmp_param_fixed_rate_clk {
unsigned int id;
char *name;
const char *parent_name;
unsigned long flags;
unsigned long fixed_rate;
};
void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
struct mmp_param_fixed_rate_clk *clks,
int size);
struct mmp_param_fixed_factor_clk {
unsigned int id;
char *name;
const char *parent_name;
unsigned long mult;
unsigned long div;
unsigned long flags;
};
void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
struct mmp_param_fixed_factor_clk *clks,
int size);
struct mmp_param_general_gate_clk {
unsigned int id;
const char *name;
const char *parent_name;
unsigned long flags;
unsigned long offset;
u8 bit_idx;
u8 gate_flags;
spinlock_t *lock;
};
void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
struct mmp_param_general_gate_clk *clks,
void __iomem *base, int size);
struct mmp_param_gate_clk {
unsigned int id;
char *name;
const char *parent_name;
unsigned long flags;
unsigned long offset;
u32 mask;
u32 val_enable;
u32 val_disable;
unsigned int gate_flags;
spinlock_t *lock;
};
void mmp_register_gate_clks(struct mmp_clk_unit *unit,
struct mmp_param_gate_clk *clks,
void __iomem *base, int size);
struct mmp_param_mux_clk {
unsigned int id;
char *name;
const char **parent_name;
u8 num_parents;
unsigned long flags;
unsigned long offset;
u8 shift;
u8 width;
u8 mux_flags;
spinlock_t *lock;
};
void mmp_register_mux_clks(struct mmp_clk_unit *unit,
struct mmp_param_mux_clk *clks,
void __iomem *base, int size);
struct mmp_param_div_clk {
unsigned int id;
char *name;
const char *parent_name;
unsigned long flags;
unsigned long offset;
u8 shift;
u8 width;
u8 div_flags;
spinlock_t *lock;
};
void mmp_register_div_clks(struct mmp_clk_unit *unit,
struct mmp_param_div_clk *clks,
void __iomem *base, int size);
#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \
{ \
.width_div = (w_d), \
.shift_div = (s_d), \
.width_mux = (w_m), \
.shift_mux = (s_m), \
.bit_fc = (fc), \
}
void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
int nr_clks);
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
struct clk *clk);
#endif #endif
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/reset-controller.h>
#include "reset.h"
#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev)
static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev,
const struct of_phandle_args *reset_spec)
{
struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
struct mmp_clk_reset_cell *cell;
int i;
if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
return -EINVAL;
for (i = 0; i < rcdev->nr_resets; i++) {
cell = &unit->cells[i];
if (cell->clk_id == reset_spec->args[0])
break;
}
if (i == rcdev->nr_resets)
return -EINVAL;
return i;
}
static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
struct mmp_clk_reset_cell *cell;
unsigned long flags = 0;
u32 val;
cell = &unit->cells[id];
if (cell->lock)
spin_lock_irqsave(cell->lock, flags);
val = readl(cell->reg);
val |= cell->bits;
writel(val, cell->reg);
if (cell->lock)
spin_unlock_irqrestore(cell->lock, flags);
return 0;
}
static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
struct mmp_clk_reset_cell *cell;
unsigned long flags = 0;
u32 val;
cell = &unit->cells[id];
if (cell->lock)
spin_lock_irqsave(cell->lock, flags);
val = readl(cell->reg);
val &= ~cell->bits;
writel(val, cell->reg);
if (cell->lock)
spin_unlock_irqrestore(cell->lock, flags);
return 0;
}
static struct reset_control_ops mmp_clk_reset_ops = {
.assert = mmp_clk_reset_assert,
.deassert = mmp_clk_reset_deassert,
};
void mmp_clk_reset_register(struct device_node *np,
struct mmp_clk_reset_cell *cells, int nr_resets)
{
struct mmp_clk_reset_unit *unit;
unit = kzalloc(sizeof(*unit), GFP_KERNEL);
if (!unit)
return;
unit->cells = cells;
unit->rcdev.of_reset_n_cells = 1;
unit->rcdev.nr_resets = nr_resets;
unit->rcdev.ops = &mmp_clk_reset_ops;
unit->rcdev.of_node = np;
unit->rcdev.of_xlate = mmp_of_reset_xlate;
reset_controller_register(&unit->rcdev);
}
#ifndef __MACH_MMP_CLK_RESET_H
#define __MACH_MMP_CLK_RESET_H
#include <linux/reset-controller.h>
#define MMP_RESET_INVERT 1
struct mmp_clk_reset_cell {
unsigned int clk_id;
void __iomem *reg;
u32 bits;
unsigned int flags;
spinlock_t *lock;
};
struct mmp_clk_reset_unit {
struct reset_controller_dev rcdev;
struct mmp_clk_reset_cell *cells;
};
#ifdef CONFIG_RESET_CONTROLLER
void mmp_clk_reset_register(struct device_node *np,
struct mmp_clk_reset_cell *cells, int nr_resets);
#else
static inline void mmp_clk_reset_register(struct device_node *np,
struct mmp_clk_reset_cell *cells, int nr_resets)
{
}
#endif
#endif
#ifndef __DTS_MARVELL_MMP2_CLOCK_H
#define __DTS_MARVELL_MMP2_CLOCK_H
/* fixed clocks and plls */
#define MMP2_CLK_CLK32 1
#define MMP2_CLK_VCTCXO 2
#define MMP2_CLK_PLL1 3
#define MMP2_CLK_PLL1_2 8
#define MMP2_CLK_PLL1_4 9
#define MMP2_CLK_PLL1_8 10
#define MMP2_CLK_PLL1_16 11
#define MMP2_CLK_PLL1_3 12
#define MMP2_CLK_PLL1_6 13
#define MMP2_CLK_PLL1_12 14
#define MMP2_CLK_PLL1_20 15
#define MMP2_CLK_PLL2 16
#define MMP2_CLK_PLL2_2 17
#define MMP2_CLK_PLL2_4 18
#define MMP2_CLK_PLL2_8 19
#define MMP2_CLK_PLL2_16 20
#define MMP2_CLK_PLL2_3 21
#define MMP2_CLK_PLL2_6 22
#define MMP2_CLK_PLL2_12 23
#define MMP2_CLK_VCTCXO_2 24
#define MMP2_CLK_VCTCXO_4 25
#define MMP2_CLK_UART_PLL 26
#define MMP2_CLK_USB_PLL 27
/* apb periphrals */
#define MMP2_CLK_TWSI0 60
#define MMP2_CLK_TWSI1 61
#define MMP2_CLK_TWSI2 62
#define MMP2_CLK_TWSI3 63
#define MMP2_CLK_TWSI4 64
#define MMP2_CLK_TWSI5 65
#define MMP2_CLK_GPIO 66
#define MMP2_CLK_KPC 67
#define MMP2_CLK_RTC 68
#define MMP2_CLK_PWM0 69
#define MMP2_CLK_PWM1 70
#define MMP2_CLK_PWM2 71
#define MMP2_CLK_PWM3 72
#define MMP2_CLK_UART0 73
#define MMP2_CLK_UART1 74
#define MMP2_CLK_UART2 75
#define MMP2_CLK_UART3 76
#define MMP2_CLK_SSP0 77
#define MMP2_CLK_SSP1 78
#define MMP2_CLK_SSP2 79
#define MMP2_CLK_SSP3 80
/* axi periphrals */
#define MMP2_CLK_SDH0 101
#define MMP2_CLK_SDH1 102
#define MMP2_CLK_SDH2 103
#define MMP2_CLK_SDH3 104
#define MMP2_CLK_USB 105
#define MMP2_CLK_DISP0 106
#define MMP2_CLK_DISP0_MUX 107
#define MMP2_CLK_DISP0_SPHY 108
#define MMP2_CLK_DISP1 109
#define MMP2_CLK_DISP1_MUX 110
#define MMP2_CLK_CCIC_ARBITER 111
#define MMP2_CLK_CCIC0 112
#define MMP2_CLK_CCIC0_MIX 113
#define MMP2_CLK_CCIC0_PHY 114
#define MMP2_CLK_CCIC0_SPHY 115
#define MMP2_CLK_CCIC1 116
#define MMP2_CLK_CCIC1_MIX 117
#define MMP2_CLK_CCIC1_PHY 118
#define MMP2_CLK_CCIC1_SPHY 119
#define MMP2_NR_CLKS 200
#endif
#ifndef __DTS_MARVELL_PXA168_CLOCK_H
#define __DTS_MARVELL_PXA168_CLOCK_H
/* fixed clocks and plls */
#define PXA168_CLK_CLK32 1
#define PXA168_CLK_VCTCXO 2
#define PXA168_CLK_PLL1 3
#define PXA168_CLK_PLL1_2 8
#define PXA168_CLK_PLL1_4 9
#define PXA168_CLK_PLL1_8 10
#define PXA168_CLK_PLL1_16 11
#define PXA168_CLK_PLL1_6 12
#define PXA168_CLK_PLL1_12 13
#define PXA168_CLK_PLL1_24 14
#define PXA168_CLK_PLL1_48 15
#define PXA168_CLK_PLL1_96 16
#define PXA168_CLK_PLL1_13 17
#define PXA168_CLK_PLL1_13_1_5 18
#define PXA168_CLK_PLL1_2_1_5 19
#define PXA168_CLK_PLL1_3_16 20
#define PXA168_CLK_UART_PLL 27
/* apb periphrals */
#define PXA168_CLK_TWSI0 60
#define PXA168_CLK_TWSI1 61
#define PXA168_CLK_TWSI2 62
#define PXA168_CLK_TWSI3 63
#define PXA168_CLK_GPIO 64
#define PXA168_CLK_KPC 65
#define PXA168_CLK_RTC 66
#define PXA168_CLK_PWM0 67
#define PXA168_CLK_PWM1 68
#define PXA168_CLK_PWM2 69
#define PXA168_CLK_PWM3 70
#define PXA168_CLK_UART0 71
#define PXA168_CLK_UART1 72
#define PXA168_CLK_UART2 73
#define PXA168_CLK_SSP0 74
#define PXA168_CLK_SSP1 75
#define PXA168_CLK_SSP2 76
#define PXA168_CLK_SSP3 77
#define PXA168_CLK_SSP4 78
/* axi periphrals */
#define PXA168_CLK_DFC 100
#define PXA168_CLK_SDH0 101
#define PXA168_CLK_SDH1 102
#define PXA168_CLK_SDH2 103
#define PXA168_CLK_USB 104
#define PXA168_CLK_SPH 105
#define PXA168_CLK_DISP0 106
#define PXA168_CLK_CCIC0 107
#define PXA168_CLK_CCIC0_PHY 108
#define PXA168_CLK_CCIC0_SPHY 109
#define PXA168_NR_CLKS 200
#endif
#ifndef __DTS_MARVELL_PXA910_CLOCK_H
#define __DTS_MARVELL_PXA910_CLOCK_H
/* fixed clocks and plls */
#define PXA910_CLK_CLK32 1
#define PXA910_CLK_VCTCXO 2
#define PXA910_CLK_PLL1 3
#define PXA910_CLK_PLL1_2 8
#define PXA910_CLK_PLL1_4 9
#define PXA910_CLK_PLL1_8 10
#define PXA910_CLK_PLL1_16 11
#define PXA910_CLK_PLL1_6 12
#define PXA910_CLK_PLL1_12 13
#define PXA910_CLK_PLL1_24 14
#define PXA910_CLK_PLL1_48 15
#define PXA910_CLK_PLL1_96 16
#define PXA910_CLK_PLL1_13 17
#define PXA910_CLK_PLL1_13_1_5 18
#define PXA910_CLK_PLL1_2_1_5 19
#define PXA910_CLK_PLL1_3_16 20
#define PXA910_CLK_UART_PLL 27
/* apb periphrals */
#define PXA910_CLK_TWSI0 60
#define PXA910_CLK_TWSI1 61
#define PXA910_CLK_TWSI2 62
#define PXA910_CLK_TWSI3 63
#define PXA910_CLK_GPIO 64
#define PXA910_CLK_KPC 65
#define PXA910_CLK_RTC 66
#define PXA910_CLK_PWM0 67
#define PXA910_CLK_PWM1 68
#define PXA910_CLK_PWM2 69
#define PXA910_CLK_PWM3 70
#define PXA910_CLK_UART0 71
#define PXA910_CLK_UART1 72
#define PXA910_CLK_UART2 73
#define PXA910_CLK_SSP0 74
#define PXA910_CLK_SSP1 75
/* axi periphrals */
#define PXA910_CLK_DFC 100
#define PXA910_CLK_SDH0 101
#define PXA910_CLK_SDH1 102
#define PXA910_CLK_SDH2 103
#define PXA910_CLK_USB 104
#define PXA910_CLK_SPH 105
#define PXA910_CLK_DISP0 106
#define PXA910_CLK_CCIC0 107
#define PXA910_CLK_CCIC0_PHY 108
#define PXA910_CLK_CCIC0_SPHY 109
#define PXA910_NR_CLKS 200
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment