aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/boot/dts/at91sam9g25ek.dts37
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi172
-rw-r--r--arch/arm/boot/dts/at91sam9x5cm.dtsi14
-rw-r--r--arch/arm/common/timer-sp.c17
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig5
-rw-r--r--arch/arm/configs/mxs_defconfig20
-rw-r--r--arch/arm/include/asm/hardware/timer-sp.h15
-rw-r--r--arch/arm/mach-at91/Kconfig9
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c373
-rw-r--r--arch/arm/mach-at91/board-dt.c1
-rw-r--r--arch/arm/mach-at91/clock.c83
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pmc.h60
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9x5.h80
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h53
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.c5
-rw-r--r--arch/arm/mach-exynos/common.c60
-rw-r--r--arch/arm/mach-exynos/cpuidle.c151
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h7
-rw-r--r--arch/arm/mach-exynos/include/mach/pmu.h2
-rw-r--r--arch/arm/mach-exynos/mct.c21
-rw-r--r--arch/arm/mach-exynos/pm.c15
-rw-r--r--arch/arm/mach-highbank/highbank.c2
-rw-r--r--arch/arm/mach-highbank/include/mach/memory.h1
-rw-r--r--arch/arm/mach-imx/Makefile4
-rw-r--r--arch/arm/mach-imx/cpu-imx5.c36
-rw-r--r--arch/arm/mach-imx/crmregs-imx3.h1
-rw-r--r--arch/arm/mach-imx/mm-imx3.c11
-rw-r--r--arch/arm/mach-imx/mm-imx5.c10
-rw-r--r--arch/arm/mach-imx/pm-imx3.c37
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c34
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c57
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-mmc.c2
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h2
-rw-r--r--arch/arm/mach-mxs/system.c16
-rw-r--r--arch/arm/mach-omap2/id.c186
-rw-r--r--arch/arm/mach-omap2/io.c9
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig8
-rw-r--r--arch/arm/mach-s3c64xx/Makefile2
-rw-r--r--arch/arm/mach-s3c64xx/clock.c121
-rw-r--r--arch/arm/mach-s3c64xx/cpuidle.c91
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c4
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.c3
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c4
-rw-r--r--arch/arm/mach-s3c64xx/setup-usb-phy.c90
-rw-r--r--arch/arm/mach-s5pv210/Kconfig6
-rw-r--r--arch/arm/mach-s5pv210/Makefile1
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-sys.h4
-rw-r--r--arch/arm/mach-s5pv210/setup-usb-phy.c90
-rw-r--r--arch/arm/mach-tegra/Makefile3
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c24
-rw-r--r--arch/arm/mach-tegra/clock.c22
-rw-r--r--arch/arm/mach-tegra/clock.h15
-rw-r--r--arch/arm/mach-tegra/common.c1
-rw-r--r--arch/arm/mach-tegra/cpuidle.c107
-rw-r--r--arch/arm/mach-tegra/flowctrl.h37
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h10
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h3
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h7
-rw-r--r--arch/arm/mach-tegra/irq.c20
-rw-r--r--arch/arm/mach-tegra/sleep.S91
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c30
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks.c3099
-rw-r--r--arch/arm/plat-mxc/cpu.c24
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h9
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h7
-rw-r--r--arch/arm/plat-s5p/Kconfig10
-rw-r--r--arch/arm/plat-s5p/sleep.S44
-rw-r--r--arch/arm/plat-samsung/clock.c12
-rw-r--r--arch/arm/plat-samsung/dev-backlight.c4
-rw-r--r--arch/arm/plat-samsung/devs.c68
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h5
76 files changed, 5351 insertions, 346 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0e8db19899c..dae718ab1d6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1131,6 +1131,7 @@ config PLAT_VERSATILE
1131config ARM_TIMER_SP804 1131config ARM_TIMER_SP804
1132 bool 1132 bool
1133 select CLKSRC_MMIO 1133 select CLKSRC_MMIO
1134 select HAVE_SCHED_CLOCK
1134 1135
1135source arch/arm/mm/Kconfig 1136source arch/arm/mm/Kconfig
1136 1137
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
new file mode 100644
index 00000000000..e64eb932083
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -0,0 +1,37 @@
1/*
2 * at91sam9g25ek.dts - Device Tree file for AT91SAM9G25-EK board
3 *
4 * Copyright (C) 2012 Atmel,
5 * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
6 *
7 * Licensed under GPLv2 or later.
8 */
9/dts-v1/;
10/include/ "at91sam9x5.dtsi"
11/include/ "at91sam9x5cm.dtsi"
12
13/ {
14 model = "Atmel AT91SAM9G25-EK";
15 compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
16
17 chosen {
18 bootargs = "128M console=ttyS0,115200 mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs) root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
19 };
20
21 ahb {
22 apb {
23 dbgu: serial@fffff200 {
24 status = "okay";
25 };
26
27 usart0: serial@f801c000 {
28 status = "okay";
29 };
30
31 macb0: ethernet@f802c000 {
32 phy-mode = "rmii";
33 status = "okay";
34 };
35 };
36 };
37};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
new file mode 100644
index 00000000000..e91391f5073
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -0,0 +1,172 @@
1/*
2 * at91sam9x5.dtsi - Device Tree Include file for AT91SAM9x5 family SoC
3 * applies to AT91SAM9G15, AT91SAM9G25, AT91SAM9G35,
4 * AT91SAM9X25, AT91SAM9X35 SoC
5 *
6 * Copyright (C) 2012 Atmel,
7 * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
8 *
9 * Licensed under GPLv2 or later.
10 */
11
12/include/ "skeleton.dtsi"
13
14/ {
15 model = "Atmel AT91SAM9x5 family SoC";
16 compatible = "atmel,at91sam9x5";
17 interrupt-parent = <&aic>;
18
19 aliases {
20 serial0 = &dbgu;
21 serial1 = &usart0;
22 serial2 = &usart1;
23 serial3 = &usart2;
24 gpio0 = &pioA;
25 gpio1 = &pioB;
26 gpio2 = &pioC;
27 gpio3 = &pioD;
28 tcb0 = &tcb0;
29 tcb1 = &tcb1;
30 };
31 cpus {
32 cpu@0 {
33 compatible = "arm,arm926ejs";
34 };
35 };
36
37 memory@20000000 {
38 reg = <0x20000000 0x10000000>;
39 };
40
41 ahb {
42 compatible = "simple-bus";
43 #address-cells = <1>;
44 #size-cells = <1>;
45 ranges;
46
47 apb {
48 compatible = "simple-bus";
49 #address-cells = <1>;
50 #size-cells = <1>;
51 ranges;
52
53 aic: interrupt-controller@fffff000 {
54 #interrupt-cells = <2>;
55 compatible = "atmel,at91rm9200-aic";
56 interrupt-controller;
57 interrupt-parent;
58 reg = <0xfffff000 0x200>;
59 };
60
61 pit: timer@fffffe30 {
62 compatible = "atmel,at91sam9260-pit";
63 reg = <0xfffffe30 0xf>;
64 interrupts = <1 4>;
65 };
66
67 tcb0: timer@f8008000 {
68 compatible = "atmel,at91sam9x5-tcb";
69 reg = <0xf8008000 0x100>;
70 interrupts = <17 4>;
71 };
72
73 tcb1: timer@f800c000 {
74 compatible = "atmel,at91sam9x5-tcb";
75 reg = <0xf800c000 0x100>;
76 interrupts = <17 4>;
77 };
78
79 dma0: dma-controller@ffffec00 {
80 compatible = "atmel,at91sam9g45-dma";
81 reg = <0xffffec00 0x200>;
82 interrupts = <20 4>;
83 };
84
85 dma1: dma-controller@ffffee00 {
86 compatible = "atmel,at91sam9g45-dma";
87 reg = <0xffffee00 0x200>;
88 interrupts = <21 4>;
89 };
90
91 pioA: gpio@fffff400 {
92 compatible = "atmel,at91rm9200-gpio";
93 reg = <0xfffff400 0x100>;
94 interrupts = <2 4>;
95 #gpio-cells = <2>;
96 gpio-controller;
97 };
98
99 pioB: gpio@fffff600 {
100 compatible = "atmel,at91rm9200-gpio";
101 reg = <0xfffff600 0x100>;
102 interrupts = <2 4>;
103 #gpio-cells = <2>;
104 gpio-controller;
105 };
106
107 pioC: gpio@fffff800 {
108 compatible = "atmel,at91rm9200-gpio";
109 reg = <0xfffff800 0x100>;
110 interrupts = <3 4>;
111 #gpio-cells = <2>;
112 gpio-controller;
113 };
114
115 pioD: gpio@fffffa00 {
116 compatible = "atmel,at91rm9200-gpio";
117 reg = <0xfffffa00 0x100>;
118 interrupts = <3 4>;
119 #gpio-cells = <2>;
120 gpio-controller;
121 };
122
123 dbgu: serial@fffff200 {
124 compatible = "atmel,at91sam9260-usart";
125 reg = <0xfffff200 0x200>;
126 interrupts = <1 4>;
127 status = "disabled";
128 };
129
130 usart0: serial@f801c000 {
131 compatible = "atmel,at91sam9260-usart";
132 reg = <0xf801c000 0x200>;
133 interrupts = <5 4>;
134 atmel,use-dma-rx;
135 atmel,use-dma-tx;
136 status = "disabled";
137 };
138
139 usart1: serial@f8020000 {
140 compatible = "atmel,at91sam9260-usart";
141 reg = <0xf8020000 0x200>;
142 interrupts = <6 4>;
143 atmel,use-dma-rx;
144 atmel,use-dma-tx;
145 status = "disabled";
146 };
147
148 usart2: serial@f8024000 {
149 compatible = "atmel,at91sam9260-usart";
150 reg = <0xf8024000 0x200>;
151 interrupts = <7 4>;
152 atmel,use-dma-rx;
153 atmel,use-dma-tx;
154 status = "disabled";
155 };
156
157 macb0: ethernet@f802c000 {
158 compatible = "cdns,at32ap7000-macb", "cdns,macb";
159 reg = <0xf802c000 0x100>;
160 interrupts = <24 4>;
161 status = "disabled";
162 };
163
164 macb1: ethernet@f8030000 {
165 compatible = "cdns,at32ap7000-macb", "cdns,macb";
166 reg = <0xf8030000 0x100>;
167 interrupts = <27 4>;
168 status = "disabled";
169 };
170 };
171 };
172};
diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi
new file mode 100644
index 00000000000..4ab5a77f4af
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi
@@ -0,0 +1,14 @@
1/*
2 * at91sam9x5cm.dtsi - Device Tree Include file for AT91SAM9x5 CPU Module
3 *
4 * Copyright (C) 2012 Atmel,
5 * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
6 *
7 * Licensed under GPLv2 or later.
8 */
9
10/ {
11 memory@20000000 {
12 reg = <0x20000000 0x8000000>;
13 };
14};
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 8794a34eae6..df13a3ffff3 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -26,6 +26,7 @@
26#include <linux/irq.h> 26#include <linux/irq.h>
27#include <linux/io.h> 27#include <linux/io.h>
28 28
29#include <asm/sched_clock.h>
29#include <asm/hardware/arm_timer.h> 30#include <asm/hardware/arm_timer.h>
30 31
31static long __init sp804_get_clock_rate(const char *name) 32static long __init sp804_get_clock_rate(const char *name)
@@ -67,7 +68,16 @@ static long __init sp804_get_clock_rate(const char *name)
67 return rate; 68 return rate;
68} 69}
69 70
70void __init sp804_clocksource_init(void __iomem *base, const char *name) 71static void __iomem *sched_clock_base;
72
73static u32 sp804_read(void)
74{
75 return ~readl_relaxed(sched_clock_base + TIMER_VALUE);
76}
77
78void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
79 const char *name,
80 int use_sched_clock)
71{ 81{
72 long rate = sp804_get_clock_rate(name); 82 long rate = sp804_get_clock_rate(name);
73 83
@@ -83,6 +93,11 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)
83 93
84 clocksource_mmio_init(base + TIMER_VALUE, name, 94 clocksource_mmio_init(base + TIMER_VALUE, name,
85 rate, 200, 32, clocksource_mmio_readl_down); 95 rate, 200, 32, clocksource_mmio_readl_down);
96
97 if (use_sched_clock) {
98 sched_clock_base = base;
99 setup_sched_clock(sp804_read, 32, rate);
100 }
86} 101}
87 102
88 103
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 3a4fb2e5fc6..3cd60690517 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -5,6 +5,7 @@ CONFIG_SYSVIPC=y
5CONFIG_LOG_BUF_SHIFT=18 5CONFIG_LOG_BUF_SHIFT=18
6CONFIG_CGROUPS=y 6CONFIG_CGROUPS=y
7CONFIG_RELAY=y 7CONFIG_RELAY=y
8CONFIG_BLK_DEV_INITRD=y
8CONFIG_EXPERT=y 9CONFIG_EXPERT=y
9# CONFIG_SLUB_DEBUG is not set 10# CONFIG_SLUB_DEBUG is not set
10# CONFIG_COMPAT_BRK is not set 11# CONFIG_COMPAT_BRK is not set
@@ -12,7 +13,6 @@ CONFIG_MODULES=y
12CONFIG_MODULE_UNLOAD=y 13CONFIG_MODULE_UNLOAD=y
13CONFIG_MODVERSIONS=y 14CONFIG_MODVERSIONS=y
14CONFIG_MODULE_SRCVERSION_ALL=y 15CONFIG_MODULE_SRCVERSION_ALL=y
15# CONFIG_LBDAF is not set
16# CONFIG_BLK_DEV_BSG is not set 16# CONFIG_BLK_DEV_BSG is not set
17CONFIG_ARCH_MXC=y 17CONFIG_ARCH_MXC=y
18CONFIG_MACH_MX31LILLY=y 18CONFIG_MACH_MX31LILLY=y
@@ -26,7 +26,6 @@ CONFIG_MACH_ARMADILLO5X0=y
26CONFIG_MACH_KZM_ARM11_01=y 26CONFIG_MACH_KZM_ARM11_01=y
27CONFIG_MACH_PCM043=y 27CONFIG_MACH_PCM043=y
28CONFIG_MACH_MX35_3DS=y 28CONFIG_MACH_MX35_3DS=y
29CONFIG_MACH_EUKREA_CPUIMX35=y
30CONFIG_MACH_VPR200=y 29CONFIG_MACH_VPR200=y
31CONFIG_MACH_IMX51_DT=y 30CONFIG_MACH_IMX51_DT=y
32CONFIG_MACH_MX51_3DS=y 31CONFIG_MACH_MX51_3DS=y
@@ -83,7 +82,6 @@ CONFIG_NETDEVICES=y
83# CONFIG_NET_VENDOR_BROADCOM is not set 82# CONFIG_NET_VENDOR_BROADCOM is not set
84# CONFIG_NET_VENDOR_CHELSIO is not set 83# CONFIG_NET_VENDOR_CHELSIO is not set
85# CONFIG_NET_VENDOR_FARADAY is not set 84# CONFIG_NET_VENDOR_FARADAY is not set
86CONFIG_FEC=y
87# CONFIG_NET_VENDOR_INTEL is not set 85# CONFIG_NET_VENDOR_INTEL is not set
88# CONFIG_NET_VENDOR_MARVELL is not set 86# CONFIG_NET_VENDOR_MARVELL is not set
89# CONFIG_NET_VENDOR_MICREL is not set 87# CONFIG_NET_VENDOR_MICREL is not set
@@ -126,6 +124,7 @@ CONFIG_WATCHDOG=y
126CONFIG_IMX2_WDT=y 124CONFIG_IMX2_WDT=y
127CONFIG_MFD_MC13XXX=y 125CONFIG_MFD_MC13XXX=y
128CONFIG_REGULATOR=y 126CONFIG_REGULATOR=y
127CONFIG_REGULATOR_FIXED_VOLTAGE=y
129CONFIG_REGULATOR_MC13892=y 128CONFIG_REGULATOR_MC13892=y
130CONFIG_USB=y 129CONFIG_USB=y
131CONFIG_USB_EHCI_HCD=y 130CONFIG_USB_EHCI_HCD=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 6ee781bf6bf..1ebbf451c48 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -77,10 +77,10 @@ CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
77CONFIG_SERIAL_AMBA_PL011=y 77CONFIG_SERIAL_AMBA_PL011=y
78CONFIG_SERIAL_AMBA_PL011_CONSOLE=y 78CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
79# CONFIG_HW_RANDOM is not set 79# CONFIG_HW_RANDOM is not set
80CONFIG_I2C=m 80CONFIG_I2C=y
81# CONFIG_I2C_COMPAT is not set 81# CONFIG_I2C_COMPAT is not set
82CONFIG_I2C_CHARDEV=m 82CONFIG_I2C_CHARDEV=y
83CONFIG_I2C_MXS=m 83CONFIG_I2C_MXS=y
84CONFIG_SPI=y 84CONFIG_SPI=y
85CONFIG_SPI_GPIO=m 85CONFIG_SPI_GPIO=m
86CONFIG_DEBUG_GPIO=y 86CONFIG_DEBUG_GPIO=y
@@ -90,6 +90,20 @@ CONFIG_GPIO_SYSFS=y
90CONFIG_DISPLAY_SUPPORT=m 90CONFIG_DISPLAY_SUPPORT=m
91# CONFIG_HID_SUPPORT is not set 91# CONFIG_HID_SUPPORT is not set
92# CONFIG_USB_SUPPORT is not set 92# CONFIG_USB_SUPPORT is not set
93CONFIG_SOUND=y
94CONFIG_SND=y
95CONFIG_SND_TIMER=y
96CONFIG_SND_PCM=y
97CONFIG_SND_JACK=y
98CONFIG_SND_DRIVERS=y
99CONFIG_SND_ARM=y
100CONFIG_SND_SOC=y
101CONFIG_SND_MXS_SOC=y
102CONFIG_SND_SOC_MXS_SGTL5000=y
103CONFIG_SND_SOC_I2C_AND_SPI=y
104CONFIG_SND_SOC_SGTL5000=y
105CONFIG_REGULATOR=y
106CONFIG_REGULATOR_FIXED_VOLTAGE=y
93CONFIG_MMC=y 107CONFIG_MMC=y
94CONFIG_MMC_MXS=y 108CONFIG_MMC_MXS=y
95CONFIG_RTC_CLASS=y 109CONFIG_RTC_CLASS=y
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 4384d81eee7..2dd9d3f83f2 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -1,2 +1,15 @@
1void sp804_clocksource_init(void __iomem *, const char *); 1void __sp804_clocksource_and_sched_clock_init(void __iomem *,
2 const char *, int);
3
4static inline void sp804_clocksource_init(void __iomem *base, const char *name)
5{
6 __sp804_clocksource_and_sched_clock_init(base, name, 0);
7}
8
9static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
10 const char *name)
11{
12 __sp804_clocksource_and_sched_clock_init(base, name, 1);
13}
14
2void sp804_clockevents_init(void __iomem *, unsigned int, const char *); 15void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 0284e66c47f..e55cdcbd81f 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -102,6 +102,15 @@ config ARCH_AT91SAM9G45
102 select HAVE_AT91_DBGU1 102 select HAVE_AT91_DBGU1
103 select AT91_SAM9G45_RESET 103 select AT91_SAM9G45_RESET
104 104
105config ARCH_AT91SAM9X5
106 bool "AT91SAM9x5 family"
107 select CPU_ARM926T
108 select GENERIC_CLOCKEVENTS
109 select HAVE_FB_ATMEL
110 select HAVE_NET_MACB
111 select HAVE_AT91_DBGU0
112 select AT91_SAM9G45_RESET
113
105config ARCH_AT91X40 114config ARCH_AT91X40
106 bool "AT91x40" 115 bool "AT91x40"
107 select ARCH_USES_GETTIMEOFFSET 116 select ARCH_USES_GETTIMEOFFSET
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index aeb76f1690d..1b6518518d9 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d
20obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o 20obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
21obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o 21obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
22obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o 22obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
23obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o
23obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o 24obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
24 25
25# AT91RM9200 board-specific support 26# AT91RM9200 board-specific support
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
new file mode 100644
index 00000000000..1c3444d2ee0
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -0,0 +1,373 @@
1/*
2 * Chip-specific setup code for the AT91SAM9x5 family
3 *
4 * Copyright (C) 2010-2012 Atmel Corporation.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/module.h>
10#include <linux/dma-mapping.h>
11
12#include <asm/irq.h>
13#include <asm/mach/arch.h>
14#include <asm/mach/map.h>
15#include <mach/at91sam9x5.h>
16#include <mach/at91_pmc.h>
17#include <mach/cpu.h>
18#include <mach/board.h>
19
20#include "soc.h"
21#include "generic.h"
22#include "clock.h"
23#include "sam9_smc.h"
24
25/* --------------------------------------------------------------------
26 * Clocks
27 * -------------------------------------------------------------------- */
28
29/*
30 * The peripheral clocks.
31 */
32static struct clk pioAB_clk = {
33 .name = "pioAB_clk",
34 .pmc_mask = 1 << AT91SAM9X5_ID_PIOAB,
35 .type = CLK_TYPE_PERIPHERAL,
36};
37static struct clk pioCD_clk = {
38 .name = "pioCD_clk",
39 .pmc_mask = 1 << AT91SAM9X5_ID_PIOCD,
40 .type = CLK_TYPE_PERIPHERAL,
41};
42static struct clk smd_clk = {
43 .name = "smd_clk",
44 .pmc_mask = 1 << AT91SAM9X5_ID_SMD,
45 .type = CLK_TYPE_PERIPHERAL,
46};
47static struct clk usart0_clk = {
48 .name = "usart0_clk",
49 .pmc_mask = 1 << AT91SAM9X5_ID_USART0,
50 .type = CLK_TYPE_PERIPHERAL,
51};
52static struct clk usart1_clk = {
53 .name = "usart1_clk",
54 .pmc_mask = 1 << AT91SAM9X5_ID_USART1,
55 .type = CLK_TYPE_PERIPHERAL,
56};
57static struct clk usart2_clk = {
58 .name = "usart2_clk",
59 .pmc_mask = 1 << AT91SAM9X5_ID_USART2,
60 .type = CLK_TYPE_PERIPHERAL,
61};
62/* USART3 clock - Only for sam9g25/sam9x25 */
63static struct clk usart3_clk = {
64 .name = "usart3_clk",
65 .pmc_mask = 1 << AT91SAM9X5_ID_USART3,
66 .type = CLK_TYPE_PERIPHERAL,
67};
68static struct clk twi0_clk = {
69 .name = "twi0_clk",
70 .pmc_mask = 1 << AT91SAM9X5_ID_TWI0,
71 .type = CLK_TYPE_PERIPHERAL,
72};
73static struct clk twi1_clk = {
74 .name = "twi1_clk",
75 .pmc_mask = 1 << AT91SAM9X5_ID_TWI1,
76 .type = CLK_TYPE_PERIPHERAL,
77};
78static struct clk twi2_clk = {
79 .name = "twi2_clk",
80 .pmc_mask = 1 << AT91SAM9X5_ID_TWI2,
81 .type = CLK_TYPE_PERIPHERAL,
82};
83static struct clk mmc0_clk = {
84 .name = "mci0_clk",
85 .pmc_mask = 1 << AT91SAM9X5_ID_MCI0,
86 .type = CLK_TYPE_PERIPHERAL,
87};
88static struct clk spi0_clk = {
89 .name = "spi0_clk",
90 .pmc_mask = 1 << AT91SAM9X5_ID_SPI0,
91 .type = CLK_TYPE_PERIPHERAL,
92};
93static struct clk spi1_clk = {
94 .name = "spi1_clk",
95 .pmc_mask = 1 << AT91SAM9X5_ID_SPI1,
96 .type = CLK_TYPE_PERIPHERAL,
97};
98static struct clk uart0_clk = {
99 .name = "uart0_clk",
100 .pmc_mask = 1 << AT91SAM9X5_ID_UART0,
101 .type = CLK_TYPE_PERIPHERAL,
102};
103static struct clk uart1_clk = {
104 .name = "uart1_clk",
105 .pmc_mask = 1 << AT91SAM9X5_ID_UART1,
106 .type = CLK_TYPE_PERIPHERAL,
107};
108static struct clk tcb0_clk = {
109 .name = "tcb0_clk",
110 .pmc_mask = 1 << AT91SAM9X5_ID_TCB,
111 .type = CLK_TYPE_PERIPHERAL,
112};
113static struct clk pwm_clk = {
114 .name = "pwm_clk",
115 .pmc_mask = 1 << AT91SAM9X5_ID_PWM,
116 .type = CLK_TYPE_PERIPHERAL,
117};
118static struct clk adc_clk = {
119 .name = "adc_clk",
120 .pmc_mask = 1 << AT91SAM9X5_ID_ADC,
121 .type = CLK_TYPE_PERIPHERAL,
122};
123static struct clk dma0_clk = {
124 .name = "dma0_clk",
125 .pmc_mask = 1 << AT91SAM9X5_ID_DMA0,
126 .type = CLK_TYPE_PERIPHERAL,
127};
128static struct clk dma1_clk = {
129 .name = "dma1_clk",
130 .pmc_mask = 1 << AT91SAM9X5_ID_DMA1,
131 .type = CLK_TYPE_PERIPHERAL,
132};
133static struct clk uhphs_clk = {
134 .name = "uhphs_clk",
135 .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS,
136 .type = CLK_TYPE_PERIPHERAL,
137};
138static struct clk udphs_clk = {
139 .name = "udphs_clk",
140 .pmc_mask = 1 << AT91SAM9X5_ID_UDPHS,
141 .type = CLK_TYPE_PERIPHERAL,
142};
143/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */
144static struct clk macb0_clk = {
145 .name = "pclk",
146 .pmc_mask = 1 << AT91SAM9X5_ID_EMAC0,
147 .type = CLK_TYPE_PERIPHERAL,
148};
149/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */
150static struct clk lcdc_clk = {
151 .name = "lcdc_clk",
152 .pmc_mask = 1 << AT91SAM9X5_ID_LCDC,
153 .type = CLK_TYPE_PERIPHERAL,
154};
155/* isi clock - Only for sam9g25 */
156static struct clk isi_clk = {
157 .name = "isi_clk",
158 .pmc_mask = 1 << AT91SAM9X5_ID_ISI,
159 .type = CLK_TYPE_PERIPHERAL,
160};
161static struct clk mmc1_clk = {
162 .name = "mci1_clk",
163 .pmc_mask = 1 << AT91SAM9X5_ID_MCI1,
164 .type = CLK_TYPE_PERIPHERAL,
165};
166/* emac1 clock - Only for sam9x25 */
167static struct clk macb1_clk = {
168 .name = "pclk",
169 .pmc_mask = 1 << AT91SAM9X5_ID_EMAC1,
170 .type = CLK_TYPE_PERIPHERAL,
171};
172static struct clk ssc_clk = {
173 .name = "ssc_clk",
174 .pmc_mask = 1 << AT91SAM9X5_ID_SSC,
175 .type = CLK_TYPE_PERIPHERAL,
176};
177/* can0 clock - Only for sam9x35 */
178static struct clk can0_clk = {
179 .name = "can0_clk",
180 .pmc_mask = 1 << AT91SAM9X5_ID_CAN0,
181 .type = CLK_TYPE_PERIPHERAL,
182};
183/* can1 clock - Only for sam9x35 */
184static struct clk can1_clk = {
185 .name = "can1_clk",
186 .pmc_mask = 1 << AT91SAM9X5_ID_CAN1,
187 .type = CLK_TYPE_PERIPHERAL,
188};
189
190static struct clk *periph_clocks[] __initdata = {
191 &pioAB_clk,
192 &pioCD_clk,
193 &smd_clk,
194 &usart0_clk,
195 &usart1_clk,
196 &usart2_clk,
197 &twi0_clk,
198 &twi1_clk,
199 &twi2_clk,
200 &mmc0_clk,
201 &spi0_clk,
202 &spi1_clk,
203 &uart0_clk,
204 &uart1_clk,
205 &tcb0_clk,
206 &pwm_clk,
207 &adc_clk,
208 &dma0_clk,
209 &dma1_clk,
210 &uhphs_clk,
211 &udphs_clk,
212 &mmc1_clk,
213 &ssc_clk,
214 // irq0
215};
216
217static struct clk_lookup periph_clocks_lookups[] = {
218 /* lookup table for DT entries */
219 CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
220 CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk),
221 CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk),
222 CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk),
223 CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
224 CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
225 CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
226 CLKDEV_CON_ID("pioA", &pioAB_clk),
227 CLKDEV_CON_ID("pioB", &pioAB_clk),
228 CLKDEV_CON_ID("pioC", &pioCD_clk),
229 CLKDEV_CON_ID("pioD", &pioCD_clk),
230 /* additional fake clock for macb_hclk */
231 CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
232 CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
233};
234
235/*
236 * The two programmable clocks.
237 * You must configure pin multiplexing to bring these signals out.
238 */
239static struct clk pck0 = {
240 .name = "pck0",
241 .pmc_mask = AT91_PMC_PCK0,
242 .type = CLK_TYPE_PROGRAMMABLE,
243 .id = 0,
244};
245static struct clk pck1 = {
246 .name = "pck1",
247 .pmc_mask = AT91_PMC_PCK1,
248 .type = CLK_TYPE_PROGRAMMABLE,
249 .id = 1,
250};
251
252static void __init at91sam9x5_register_clocks(void)
253{
254 int i;
255
256 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
257 clk_register(periph_clocks[i]);
258
259 clkdev_add_table(periph_clocks_lookups,
260 ARRAY_SIZE(periph_clocks_lookups));
261
262 if (cpu_is_at91sam9g25()
263 || cpu_is_at91sam9x25())
264 clk_register(&usart3_clk);
265
266 if (cpu_is_at91sam9g25()
267 || cpu_is_at91sam9x25()
268 || cpu_is_at91sam9g35()
269 || cpu_is_at91sam9x35())
270 clk_register(&macb0_clk);
271
272 if (cpu_is_at91sam9g15()
273 || cpu_is_at91sam9g35()
274 || cpu_is_at91sam9x35())
275 clk_register(&lcdc_clk);
276
277 if (cpu_is_at91sam9g25())
278 clk_register(&isi_clk);
279
280 if (cpu_is_at91sam9x25())
281 clk_register(&macb1_clk);
282
283 if (cpu_is_at91sam9x25()
284 || cpu_is_at91sam9x35()) {
285 clk_register(&can0_clk);
286 clk_register(&can1_clk);
287 }
288
289 clk_register(&pck0);
290 clk_register(&pck1);
291}
292
293/* --------------------------------------------------------------------
294 * AT91SAM9x5 processor initialization
295 * -------------------------------------------------------------------- */
296
297static void __init at91sam9x5_map_io(void)
298{
299 at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
300}
301
302static void __init at91sam9x5_ioremap_registers(void)
303{
304 if (of_at91sam926x_pit_init() < 0)
305 panic("Impossible to find PIT\n");
306}
307
308void __init at91sam9x5_initialize(void)
309{
310 arm_pm_restart = at91sam9g45_restart;
311 at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0);
312
313 /* Register GPIO subsystem (using DT) */
314 at91_gpio_init(NULL, 0);
315}
316
317/* --------------------------------------------------------------------
318 * AT91SAM9x5 devices (temporary before modification of code)
319 * -------------------------------------------------------------------- */
320void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
321void __init at91_set_serial_console(unsigned portnr) {}
322struct platform_device *atmel_default_console_device = NULL;
323
324void __init at91_add_device_nand(struct atmel_nand_data *data) {}
325
326/* --------------------------------------------------------------------
327 * Interrupt initialization
328 * -------------------------------------------------------------------- */
329/*
330 * The default interrupt priority levels (0 = lowest, 7 = highest).
331 */
332static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = {
333 7, /* Advanced Interrupt Controller (FIQ) */
334 7, /* System Peripherals */
335 1, /* Parallel IO Controller A and B */
336 1, /* Parallel IO Controller C and D */
337 4, /* Soft Modem */
338 5, /* USART 0 */
339 5, /* USART 1 */
340 5, /* USART 2 */
341 5, /* USART 3 */
342 6, /* Two-Wire Interface 0 */
343 6, /* Two-Wire Interface 1 */
344 6, /* Two-Wire Interface 2 */
345 0, /* Multimedia Card Interface 0 */
346 5, /* Serial Peripheral Interface 0 */
347 5, /* Serial Peripheral Interface 1 */
348 5, /* UART 0 */
349 5, /* UART 1 */
350 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
351 0, /* Pulse Width Modulation Controller */
352 0, /* ADC Controller */
353 0, /* DMA Controller 0 */
354 0, /* DMA Controller 1 */
355 2, /* USB Host High Speed port */
356 2, /* USB Device High speed port */
357 3, /* Ethernet MAC 0 */
358 3, /* LDC Controller or Image Sensor Interface */
359 0, /* Multimedia Card Interface 1 */
360 3, /* Ethernet MAC 1 */
361 4, /* Synchronous Serial Interface */
362 4, /* CAN Controller 0 */
363 4, /* CAN Controller 1 */
364 0, /* Advanced Interrupt Controller (IRQ0) */
365};
366
367struct at91_init_soc __initdata at91sam9x5_soc = {
368 .map_io = at91sam9x5_map_io,
369 .default_irq_priority = at91sam9x5_default_irq_priority,
370 .ioremap_registers = at91sam9x5_ioremap_registers,
371 .register_clocks = at91sam9x5_register_clocks,
372 .init = at91sam9x5_initialize,
373};
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index bb6b434ec0c..05793156d17 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -109,6 +109,7 @@ static void __init at91_dt_device_init(void)
109 109
110static const char *at91_dt_board_compat[] __initdata = { 110static const char *at91_dt_board_compat[] __initdata = {
111 "atmel,at91sam9m10g45ek", 111 "atmel,at91sam9m10g45ek",
112 "atmel,at91sam9x5ek",
112 "calao,usb-a9g20", 113 "calao,usb-a9g20",
113 NULL 114 NULL
114}; 115};
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index aa04e22a9da..a5291e0e700 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -48,24 +48,37 @@
48 * Chips have some kind of clocks : group them by functionality 48 * Chips have some kind of clocks : group them by functionality
49 */ 49 */
50#define cpu_has_utmi() ( cpu_is_at91sam9rl() \ 50#define cpu_has_utmi() ( cpu_is_at91sam9rl() \
51 || cpu_is_at91sam9g45()) 51 || cpu_is_at91sam9g45() \
52 || cpu_is_at91sam9x5())
52 53
53#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ 54#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
54 || cpu_is_at91sam9g45()) 55 || cpu_is_at91sam9g45() \
56 || cpu_is_at91sam9x5())
55 57
56#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) 58#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
57 59
58#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ 60#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
59 || cpu_is_at91sam9g45())) 61 || cpu_is_at91sam9g45() \
62 || cpu_is_at91sam9x5()))
60 63
61#define cpu_has_upll() (cpu_is_at91sam9g45()) 64#define cpu_has_upll() (cpu_is_at91sam9g45() \
65 || cpu_is_at91sam9x5())
62 66
63/* USB host HS & FS */ 67/* USB host HS & FS */
64#define cpu_has_uhp() (!cpu_is_at91sam9rl()) 68#define cpu_has_uhp() (!cpu_is_at91sam9rl())
65 69
66/* USB device FS only */ 70/* USB device FS only */
67#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ 71#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
68 || cpu_is_at91sam9g45())) 72 || cpu_is_at91sam9g45() \
73 || cpu_is_at91sam9x5()))
74
75#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \
76 || cpu_is_at91sam9x5())
77
78#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \
79 || cpu_is_at91sam9x5())
80
81#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5())
69 82
70static LIST_HEAD(clocks); 83static LIST_HEAD(clocks);
71static DEFINE_SPINLOCK(clk_lock); 84static DEFINE_SPINLOCK(clk_lock);
@@ -138,13 +151,6 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
138{ 151{
139 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); 152 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
140 153
141 if (cpu_is_at91sam9g45()) {
142 if (is_on)
143 uckr |= AT91_PMC_BIASEN;
144 else
145 uckr &= ~AT91_PMC_BIASEN;
146 }
147
148 if (is_on) { 154 if (is_on) {
149 is_on = AT91_PMC_LOCKU; 155 is_on = AT91_PMC_LOCKU;
150 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); 156 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -209,11 +215,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
209 return &utmi_clk; 215 return &utmi_clk;
210 else if (cpu_has_pllb()) 216 else if (cpu_has_pllb())
211 return &pllb; 217 return &pllb;
218 break;
219 /* alternate PMC: can use master clock */
220 case AT91_PMC_CSS_MASTER:
221 return &mck;
212 } 222 }
213 223
214 return NULL; 224 return NULL;
215} 225}
216 226
227static int pmc_prescaler_divider(u32 reg)
228{
229 if (cpu_has_alt_prescaler()) {
230 return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET);
231 } else {
232 return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET);
233 }
234}
235
217static void __clk_enable(struct clk *clk) 236static void __clk_enable(struct clk *clk)
218{ 237{
219 if (clk->parent) 238 if (clk->parent)
@@ -315,12 +334,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
315{ 334{
316 unsigned long flags; 335 unsigned long flags;
317 unsigned prescale; 336 unsigned prescale;
337 unsigned long prescale_offset, css_mask;
318 unsigned long actual; 338 unsigned long actual;
319 339
320 if (!clk_is_programmable(clk)) 340 if (!clk_is_programmable(clk))
321 return -EINVAL; 341 return -EINVAL;
322 if (clk->users) 342 if (clk->users)
323 return -EBUSY; 343 return -EBUSY;
344
345 if (cpu_has_alt_prescaler()) {
346 prescale_offset = PMC_ALT_PRES_OFFSET;
347 css_mask = AT91_PMC_ALT_PCKR_CSS;
348 } else {
349 prescale_offset = PMC_PRES_OFFSET;
350 css_mask = AT91_PMC_CSS;
351 }
352
324 spin_lock_irqsave(&clk_lock, flags); 353 spin_lock_irqsave(&clk_lock, flags);
325 354
326 actual = clk->parent->rate_hz; 355 actual = clk->parent->rate_hz;
@@ -329,8 +358,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
329 u32 pckr; 358 u32 pckr;
330 359
331 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); 360 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
332 pckr &= AT91_PMC_CSS; /* clock selection */ 361 pckr &= css_mask; /* keep clock selection */
333 pckr |= prescale << 2; 362 pckr |= prescale << prescale_offset;
334 at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); 363 at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
335 clk->rate_hz = actual; 364 clk->rate_hz = actual;
336 break; 365 break;
@@ -377,11 +406,17 @@ static void __init init_programmable_clock(struct clk *clk)
377{ 406{
378 struct clk *parent; 407 struct clk *parent;
379 u32 pckr; 408 u32 pckr;
409 unsigned int css_mask;
410
411 if (cpu_has_alt_prescaler())
412 css_mask = AT91_PMC_ALT_PCKR_CSS;
413 else
414 css_mask = AT91_PMC_CSS;
380 415
381 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); 416 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
382 parent = at91_css_to_clk(pckr & AT91_PMC_CSS); 417 parent = at91_css_to_clk(pckr & css_mask);
383 clk->parent = parent; 418 clk->parent = parent;
384 clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); 419 clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
385} 420}
386 421
387#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ 422#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -663,7 +698,7 @@ int __init at91_clock_init(unsigned long main_clock)
663 if (pll_overclock) 698 if (pll_overclock)
664 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); 699 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
665 700
666 if (cpu_is_at91sam9g45()) { 701 if (cpu_has_plladiv2()) {
667 mckr = at91_sys_read(AT91_PMC_MCKR); 702 mckr = at91_sys_read(AT91_PMC_MCKR);
668 plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ 703 plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
669 } 704 }
@@ -685,6 +720,10 @@ int __init at91_clock_init(unsigned long main_clock)
685 * (obtain the USB High Speed 480 MHz when input is 12 MHz) 720 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
686 */ 721 */
687 utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; 722 utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
723
724 /* UTMI bias and PLL are managed at the same time */
725 if (cpu_has_upll())
726 utmi_clk.pmc_mask |= AT91_PMC_BIASEN;
688 } 727 }
689 728
690 /* 729 /*
@@ -703,7 +742,7 @@ int __init at91_clock_init(unsigned long main_clock)
703 mckr = at91_sys_read(AT91_PMC_MCKR); 742 mckr = at91_sys_read(AT91_PMC_MCKR);
704 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); 743 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
705 freq = mck.parent->rate_hz; 744 freq = mck.parent->rate_hz;
706 freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ 745 freq /= pmc_prescaler_divider(mckr); /* prescale */
707 if (cpu_is_at91rm9200()) { 746 if (cpu_is_at91rm9200()) {
708 mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 747 mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
709 } else if (cpu_is_at91sam9g20()) { 748 } else if (cpu_is_at91sam9g20()) {
@@ -711,13 +750,19 @@ int __init at91_clock_init(unsigned long main_clock)
711 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ 750 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
712 if (mckr & AT91_PMC_PDIV) 751 if (mckr & AT91_PMC_PDIV)
713 freq /= 2; /* processor clock division */ 752 freq /= 2; /* processor clock division */
714 } else if (cpu_is_at91sam9g45()) { 753 } else if (cpu_has_mdiv3()) {
715 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? 754 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
716 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 755 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
717 } else { 756 } else {
718 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 757 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
719 } 758 }
720 759
760 if (cpu_has_alt_prescaler()) {
761 /* Programmable clocks can use MCK */
762 mck.type |= CLK_TYPE_PRIMARY;
763 mck.id = 4;
764 }
765
721 /* Register the PMC's standard clocks */ 766 /* Register the PMC's standard clocks */
722 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) 767 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
723 at91_clk_add(standard_pmc_clocks[i]); 768 at91_clk_add(standard_pmc_clocks[i]);
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index dbdd6ae473d..f9fdbbe0c53 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -45,9 +45,13 @@
45#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ 45#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */
46 46
47#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ 47#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */
48#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ 48#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
49#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x] */ 49#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */
50#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ 50#define AT91_PMC_MOSCRCEN (1 << 3) /* Main On-Chip RC Oscillator Enable [some SAM9] */
51#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */
52#define AT91_PMC_KEY (0x37 << 16) /* MOR Writing Key */
53#define AT91_PMC_MOSCSEL (1 << 24) /* Main Oscillator Selection [some SAM9] */
54#define AT91_PMC_CFDEN (1 << 25) /* Clock Failure Detector Enable [some SAM9] */
51 55
52#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ 56#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */
53#define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ 57#define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */
@@ -72,14 +76,24 @@
72#define AT91_PMC_CSS_PLLA (2 << 0) 76#define AT91_PMC_CSS_PLLA (2 << 0)
73#define AT91_PMC_CSS_PLLB (3 << 0) 77#define AT91_PMC_CSS_PLLB (3 << 0)
74#define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ 78#define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */
75#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ 79#define PMC_PRES_OFFSET 2
76#define AT91_PMC_PRES_1 (0 << 2) 80#define AT91_PMC_PRES (7 << PMC_PRES_OFFSET) /* Master Clock Prescaler */
77#define AT91_PMC_PRES_2 (1 << 2) 81#define AT91_PMC_PRES_1 (0 << PMC_PRES_OFFSET)
78#define AT91_PMC_PRES_4 (2 << 2) 82#define AT91_PMC_PRES_2 (1 << PMC_PRES_OFFSET)
79#define AT91_PMC_PRES_8 (3 << 2) 83#define AT91_PMC_PRES_4 (2 << PMC_PRES_OFFSET)
80#define AT91_PMC_PRES_16 (4 << 2) 84#define AT91_PMC_PRES_8 (3 << PMC_PRES_OFFSET)
81#define AT91_PMC_PRES_32 (5 << 2) 85#define AT91_PMC_PRES_16 (4 << PMC_PRES_OFFSET)
82#define AT91_PMC_PRES_64 (6 << 2) 86#define AT91_PMC_PRES_32 (5 << PMC_PRES_OFFSET)
87#define AT91_PMC_PRES_64 (6 << PMC_PRES_OFFSET)
88#define PMC_ALT_PRES_OFFSET 4
89#define AT91_PMC_ALT_PRES (7 << PMC_ALT_PRES_OFFSET) /* Master Clock Prescaler [alternate location] */
90#define AT91_PMC_ALT_PRES_1 (0 << PMC_ALT_PRES_OFFSET)
91#define AT91_PMC_ALT_PRES_2 (1 << PMC_ALT_PRES_OFFSET)
92#define AT91_PMC_ALT_PRES_4 (2 << PMC_ALT_PRES_OFFSET)
93#define AT91_PMC_ALT_PRES_8 (3 << PMC_ALT_PRES_OFFSET)
94#define AT91_PMC_ALT_PRES_16 (4 << PMC_ALT_PRES_OFFSET)
95#define AT91_PMC_ALT_PRES_32 (5 << PMC_ALT_PRES_OFFSET)
96#define AT91_PMC_ALT_PRES_64 (6 << PMC_ALT_PRES_OFFSET)
83#define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ 97#define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */
84#define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ 98#define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */
85#define AT91RM9200_PMC_MDIV_2 (1 << 8) 99#define AT91RM9200_PMC_MDIV_2 (1 << 8)
@@ -103,7 +117,14 @@
103#define AT91_PMC_USBS_UPLL (1 << 0) 117#define AT91_PMC_USBS_UPLL (1 << 0)
104#define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ 118#define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */
105 119
120#define AT91_PMC_SMD (AT91_PMC + 0x3c) /* Soft Modem Clock Register [some SAM9 only] */
121#define AT91_PMC_SMDS (0x1 << 0) /* SMD input clock selection */
122#define AT91_PMC_SMD_DIV (0x1f << 8) /* SMD input clock divider */
123#define AT91_PMC_SMDDIV(n) (((n) << 8) & AT91_PMC_SMD_DIV)
124
106#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ 125#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */
126#define AT91_PMC_ALT_PCKR_CSS (0x7 << 0) /* Programmable Clock Source Selection [alternate length] */
127#define AT91_PMC_CSS_MASTER (4 << 0) /* [some SAM9 only] */
107#define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ 128#define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */
108#define AT91_PMC_CSSMCK_CSS (0 << 8) 129#define AT91_PMC_CSSMCK_CSS (0 << 8)
109#define AT91_PMC_CSSMCK_MCK (1 << 8) 130#define AT91_PMC_CSSMCK_MCK (1 << 8)
@@ -120,10 +141,25 @@
120#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ 141#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
121#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ 142#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */
122#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ 143#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */
144#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */
145#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */
146#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */
123#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */ 147#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */
124 148
125#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Write Protect Mode Register [some SAM9] */ 149#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Write Protect Mode Register [some SAM9] */
126#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ 150#define AT91_PMC_WPEN (0x1 << 0) /* Write Protect Enable */
151#define AT91_PMC_WPKEY (0xffffff << 8) /* Write Protect Key */
152#define AT91_PMC_PROTKEY (0x504d43 << 8) /* Activation Code */
153
154#define AT91_PMC_WPSR (AT91_PMC + 0xe8) /* Write Protect Status Register [some SAM9] */
155#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */
156#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */
127 157
158#define AT91_PMC_PCR (AT91_PMC + 0x10c) /* Peripheral Control Register [some SAM9] */
159#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */
160#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */
161#define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */
162#define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV)
163#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
128 164
129#endif 165#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h
new file mode 100644
index 00000000000..8476871a2f9
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h
@@ -0,0 +1,80 @@
1/*
2 * Chip-specific header file for the AT91SAM9x5 family
3 *
4 * Copyright (C) 2009-2012 Atmel Corporation.
5 *
6 * Common definitions.
7 * Based on AT91SAM9x5 datasheet.
8 *
9 * Licensed under GPLv2 or later.
10 */
11
12#ifndef AT91SAM9X5_H
13#define AT91SAM9X5_H
14
15/*
16 * Peripheral identifiers/interrupts.
17 */
18#define AT91SAM9X5_ID_PIOAB 2 /* Parallel I/O Controller A and B */
19#define AT91SAM9X5_ID_PIOCD 3 /* Parallel I/O Controller C and D */
20#define AT91SAM9X5_ID_SMD 4 /* SMD Soft Modem (SMD) */
21#define AT91SAM9X5_ID_USART0 5 /* USART 0 */
22#define AT91SAM9X5_ID_USART1 6 /* USART 1 */
23#define AT91SAM9X5_ID_USART2 7 /* USART 2 */
24#define AT91SAM9X5_ID_USART3 8 /* USART 3 */
25#define AT91SAM9X5_ID_TWI0 9 /* Two-Wire Interface 0 */
26#define AT91SAM9X5_ID_TWI1 10 /* Two-Wire Interface 1 */
27#define AT91SAM9X5_ID_TWI2 11 /* Two-Wire Interface 2 */
28#define AT91SAM9X5_ID_MCI0 12 /* High Speed Multimedia Card Interface 0 */
29#define AT91SAM9X5_ID_SPI0 13 /* Serial Peripheral Interface 0 */
30#define AT91SAM9X5_ID_SPI1 14 /* Serial Peripheral Interface 1 */
31#define AT91SAM9X5_ID_UART0 15 /* UART 0 */
32#define AT91SAM9X5_ID_UART1 16 /* UART 1 */
33#define AT91SAM9X5_ID_TCB 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */
34#define AT91SAM9X5_ID_PWM 18 /* Pulse Width Modulation Controller */
35#define AT91SAM9X5_ID_ADC 19 /* ADC Controller */
36#define AT91SAM9X5_ID_DMA0 20 /* DMA Controller 0 */
37#define AT91SAM9X5_ID_DMA1 21 /* DMA Controller 1 */
38#define AT91SAM9X5_ID_UHPHS 22 /* USB Host High Speed */
39#define AT91SAM9X5_ID_UDPHS 23 /* USB Device High Speed */
40#define AT91SAM9X5_ID_EMAC0 24 /* Ethernet MAC0 */
41#define AT91SAM9X5_ID_LCDC 25 /* LCD Controller */
42#define AT91SAM9X5_ID_ISI 25 /* Image Sensor Interface */
43#define AT91SAM9X5_ID_MCI1 26 /* High Speed Multimedia Card Interface 1 */
44#define AT91SAM9X5_ID_EMAC1 27 /* Ethernet MAC1 */
45#define AT91SAM9X5_ID_SSC 28 /* Synchronous Serial Controller */
46#define AT91SAM9X5_ID_CAN0 29 /* CAN Controller 0 */
47#define AT91SAM9X5_ID_CAN1 30 /* CAN Controller 1 */
48#define AT91SAM9X5_ID_IRQ0 31 /* Advanced Interrupt Controller */
49
50/*
51 * User Peripheral physical base addresses.
52 */
53#define AT91SAM9X5_BASE_USART0 0xf801c000
54#define AT91SAM9X5_BASE_USART1 0xf8020000
55#define AT91SAM9X5_BASE_USART2 0xf8024000
56
57/*
58 * System Peripherals (offset from AT91_BASE_SYS)
59 */
60#define AT91_DDRSDRC0 (0xffffe800 - AT91_BASE_SYS)
61#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
62
63/*
64 * Base addresses for early serial code (uncompress.h)
65 */
66#define AT91_DBGU AT91_BASE_DBGU0
67#define AT91_USART0 AT91SAM9X5_BASE_USART0
68#define AT91_USART1 AT91SAM9X5_BASE_USART1
69#define AT91_USART2 AT91SAM9X5_BASE_USART2
70
71/*
72 * Internal Memory.
73 */
74#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */
75#define AT91SAM9X5_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */
76
77#define AT91SAM9X5_ROM_BASE 0x00400000 /* Internal ROM base address */
78#define AT91SAM9X5_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */
79
80#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h
new file mode 100644
index 00000000000..a606d396647
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h
@@ -0,0 +1,53 @@
1/*
2 * Matrix-centric header file for the AT91SAM9x5 family
3 *
4 * Copyright (C) 2009-2012 Atmel Corporation.
5 *
6 * Only EBI related registers.
7 * Write Protect register definitions may be useful.
8 *
9 * Licensed under GPLv2 or later.
10 */
11
12#ifndef AT91SAM9X5_MATRIX_H
13#define AT91SAM9X5_MATRIX_H
14
15#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */
16#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
17#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
18#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
19#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
20#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
21#define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3)
22#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
23#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
24#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
25#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
26#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
27#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
28#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
29#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
30#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
31#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
32#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
33#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
34#define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */
35#define AT91_MATRIX_NFD0_ON_D0 (0 << 24)
36#define AT91_MATRIX_NFD0_ON_D16 (1 << 24)
37#define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */
38#define AT91_MATRIX_MP_OFF (0 << 25)
39#define AT91_MATRIX_MP_ON (1 << 25)
40
41#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
42#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
43#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
44#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
45#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
46
47#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
48#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
49#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
50#define AT91_MATRIX_WPSR_WPV (1 << 0)
51#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
52
53#endif
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index c213f28628c..fd7dce4f737 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -34,6 +34,8 @@
34#include <mach/at91sam9rl.h> 34#include <mach/at91sam9rl.h>
35#elif defined(CONFIG_ARCH_AT91SAM9G45) 35#elif defined(CONFIG_ARCH_AT91SAM9G45)
36#include <mach/at91sam9g45.h> 36#include <mach/at91sam9g45.h>
37#elif defined(CONFIG_ARCH_AT91SAM9X5)
38#include <mach/at91sam9x5.h>
37#elif defined(CONFIG_ARCH_AT91X40) 39#elif defined(CONFIG_ARCH_AT91X40)
38#include <mach/at91x40.h> 40#include <mach/at91x40.h>
39#else 41#else
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 31b59e65463..060dde7d7ad 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -471,6 +471,11 @@ static struct clk exynos4_init_clocks_off[] = {
471 .enable = exynos4_clk_ip_cam_ctrl, 471 .enable = exynos4_clk_ip_cam_ctrl,
472 .ctrlbit = (1 << 5), 472 .ctrlbit = (1 << 5),
473 }, { 473 }, {
474 .name = "jpeg",
475 .id = 0,
476 .enable = exynos4_clk_ip_cam_ctrl,
477 .ctrlbit = (1 << 6),
478 }, {
474 .name = "fimc", 479 .name = "fimc",
475 .devname = "exynos4-fimc.0", 480 .devname = "exynos4-fimc.0",
476 .enable = exynos4_clk_ip_cam_ctrl, 481 .enable = exynos4_clk_ip_cam_ctrl,
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index f494db872c6..97ca2592ce8 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -26,10 +26,12 @@
26#include <asm/hardware/gic.h> 26#include <asm/hardware/gic.h>
27#include <asm/mach/map.h> 27#include <asm/mach/map.h>
28#include <asm/mach/irq.h> 28#include <asm/mach/irq.h>
29#include <asm/cacheflush.h>
29 30
30#include <mach/regs-irq.h> 31#include <mach/regs-irq.h>
31#include <mach/regs-pmu.h> 32#include <mach/regs-pmu.h>
32#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/pmu.h>
33 35
34#include <plat/cpu.h> 36#include <plat/cpu.h>
35#include <plat/clock.h> 37#include <plat/clock.h>
@@ -45,6 +47,8 @@
45#include <plat/regs-serial.h> 47#include <plat/regs-serial.h>
46 48
47#include "common.h" 49#include "common.h"
50#define L2_AUX_VAL 0x7C470001
51#define L2_AUX_MASK 0xC200ffff
48 52
49static const char name_exynos4210[] = "EXYNOS4210"; 53static const char name_exynos4210[] = "EXYNOS4210";
50static const char name_exynos4212[] = "EXYNOS4212"; 54static const char name_exynos4212[] = "EXYNOS4212";
@@ -173,7 +177,12 @@ static struct map_desc exynos4_iodesc[] __initdata = {
173 }, { 177 }, {
174 .virtual = (unsigned long)S5P_VA_DMC0, 178 .virtual = (unsigned long)S5P_VA_DMC0,
175 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), 179 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
176 .length = SZ_4K, 180 .length = SZ_64K,
181 .type = MT_DEVICE,
182 }, {
183 .virtual = (unsigned long)S5P_VA_DMC1,
184 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
185 .length = SZ_64K,
177 .type = MT_DEVICE, 186 .type = MT_DEVICE,
178 }, { 187 }, {
179 .virtual = (unsigned long)S3C_VA_USB_HSPHY, 188 .virtual = (unsigned long)S3C_VA_USB_HSPHY,
@@ -433,23 +442,48 @@ core_initcall(exynos4_core_init);
433#ifdef CONFIG_CACHE_L2X0 442#ifdef CONFIG_CACHE_L2X0
434static int __init exynos4_l2x0_cache_init(void) 443static int __init exynos4_l2x0_cache_init(void)
435{ 444{
436 /* TAG, Data Latency Control: 2cycle */ 445 int ret;
437 __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); 446 ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
447 if (!ret) {
448 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
449 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
450 return 0;
451 }
438 452
439 if (soc_is_exynos4210()) 453 if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
440 __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); 454 l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
441 else if (soc_is_exynos4212() || soc_is_exynos4412()) 455 /* TAG, Data Latency Control: 2 cycles */
442 __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); 456 l2x0_saved_regs.tag_latency = 0x110;
457
458 if (soc_is_exynos4212() || soc_is_exynos4412())
459 l2x0_saved_regs.data_latency = 0x120;
460 else
461 l2x0_saved_regs.data_latency = 0x110;
462
463 l2x0_saved_regs.prefetch_ctrl = 0x30000007;
464 l2x0_saved_regs.pwr_ctrl =
465 (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
443 466
444 /* L2X0 Prefetch Control */ 467 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
445 __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
446 468
447 /* L2X0 Power Control */ 469 __raw_writel(l2x0_saved_regs.tag_latency,
448 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, 470 S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
449 S5P_VA_L2CC + L2X0_POWER_CTRL); 471 __raw_writel(l2x0_saved_regs.data_latency,
472 S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
450 473
451 l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); 474 /* L2X0 Prefetch Control */
475 __raw_writel(l2x0_saved_regs.prefetch_ctrl,
476 S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
477
478 /* L2X0 Power Control */
479 __raw_writel(l2x0_saved_regs.pwr_ctrl,
480 S5P_VA_L2CC + L2X0_POWER_CTRL);
481
482 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
483 clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
484 }
452 485
486 l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
453 return 0; 487 return 0;
454} 488}
455 489
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index 4ebb382c597..33ab4e7558a 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -11,25 +11,53 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/cpuidle.h> 13#include <linux/cpuidle.h>
14#include <linux/cpu_pm.h>
14#include <linux/io.h> 15#include <linux/io.h>
15#include <linux/export.h> 16#include <linux/export.h>
16#include <linux/time.h> 17#include <linux/time.h>
17 18
18#include <asm/proc-fns.h> 19#include <asm/proc-fns.h>
20#include <asm/smp_scu.h>
21#include <asm/suspend.h>
22#include <asm/unified.h>
23#include <mach/regs-pmu.h>
24#include <mach/pmu.h>
25
26#include <plat/cpu.h>
27
28#define REG_DIRECTGO_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \
29 S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
30 (S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
31#define REG_DIRECTGO_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
32 S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
33 (S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
34
35#define S5P_CHECK_AFTR 0xFCBA0D10
19 36
20static int exynos4_enter_idle(struct cpuidle_device *dev, 37static int exynos4_enter_idle(struct cpuidle_device *dev,
21 struct cpuidle_driver *drv, 38 struct cpuidle_driver *drv,
22 int index); 39 int index);
40static int exynos4_enter_lowpower(struct cpuidle_device *dev,
41 struct cpuidle_driver *drv,
42 int index);
23 43
24static struct cpuidle_state exynos4_cpuidle_set[] = { 44static struct cpuidle_state exynos4_cpuidle_set[] __initdata = {
25 [0] = { 45 [0] = {
26 .enter = exynos4_enter_idle, 46 .enter = exynos4_enter_idle,
27 .exit_latency = 1, 47 .exit_latency = 1,
28 .target_residency = 100000, 48 .target_residency = 100000,
29 .flags = CPUIDLE_FLAG_TIME_VALID, 49 .flags = CPUIDLE_FLAG_TIME_VALID,
30 .name = "IDLE", 50 .name = "C0",
31 .desc = "ARM clock gating(WFI)", 51 .desc = "ARM clock gating(WFI)",
32 }, 52 },
53 [1] = {
54 .enter = exynos4_enter_lowpower,
55 .exit_latency = 300,
56 .target_residency = 100000,
57 .flags = CPUIDLE_FLAG_TIME_VALID,
58 .name = "C1",
59 .desc = "ARM power down",
60 },
33}; 61};
34 62
35static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); 63static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
@@ -39,9 +67,102 @@ static struct cpuidle_driver exynos4_idle_driver = {
39 .owner = THIS_MODULE, 67 .owner = THIS_MODULE,
40}; 68};
41 69
70/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
71static void exynos4_set_wakeupmask(void)
72{
73 __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
74}
75
76static unsigned int g_pwr_ctrl, g_diag_reg;
77
78static void save_cpu_arch_register(void)
79{
80 /*read power control register*/
81 asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc");
82 /*read diagnostic register*/
83 asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
84 return;
85}
86
87static void restore_cpu_arch_register(void)
88{
89 /*write power control register*/
90 asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc");
91 /*write diagnostic register*/
92 asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
93 return;
94}
95
96static int idle_finisher(unsigned long flags)
97{
98 cpu_do_idle();
99 return 1;
100}
101
102static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
103 struct cpuidle_driver *drv,
104 int index)
105{
106 struct timeval before, after;
107 int idle_time;
108 unsigned long tmp;
109
110 local_irq_disable();
111 do_gettimeofday(&before);
112
113 exynos4_set_wakeupmask();
114
115 /* Set value of power down register for aftr mode */
116 exynos4_sys_powerdown_conf(SYS_AFTR);
117
118 __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
119 __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
120
121 save_cpu_arch_register();
122
123 /* Setting Central Sequence Register for power down mode */
124 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
125 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
126 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
127
128 cpu_pm_enter();
129 cpu_suspend(0, idle_finisher);
130
131#ifdef CONFIG_SMP
132 scu_enable(S5P_VA_SCU);
133#endif
134 cpu_pm_exit();
135
136 restore_cpu_arch_register();
137
138 /*
139 * If PMU failed while entering sleep mode, WFI will be
140 * ignored by PMU and then exiting cpu_do_idle().
141 * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
142 * in this situation.
143 */
144 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
145 if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
146 tmp |= S5P_CENTRAL_LOWPWR_CFG;
147 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
148 }
149
150 /* Clear wakeup state register */
151 __raw_writel(0x0, S5P_WAKEUP_STAT);
152
153 do_gettimeofday(&after);
154
155 local_irq_enable();
156 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
157 (after.tv_usec - before.tv_usec);
158
159 dev->last_residency = idle_time;
160 return index;
161}
162
42static int exynos4_enter_idle(struct cpuidle_device *dev, 163static int exynos4_enter_idle(struct cpuidle_device *dev,
43 struct cpuidle_driver *drv, 164 struct cpuidle_driver *drv,
44 int index) 165 int index)
45{ 166{
46 struct timeval before, after; 167 struct timeval before, after;
47 int idle_time; 168 int idle_time;
@@ -60,6 +181,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,
60 return index; 181 return index;
61} 182}
62 183
184static int exynos4_enter_lowpower(struct cpuidle_device *dev,
185 struct cpuidle_driver *drv,
186 int index)
187{
188 int new_index = index;
189
190 /* This mode only can be entered when other core's are offline */
191 if (num_online_cpus() > 1)
192 new_index = drv->safe_state_index;
193
194 if (new_index == 0)
195 return exynos4_enter_idle(dev, drv, new_index);
196 else
197 return exynos4_enter_core0_aftr(dev, drv, new_index);
198}
199
63static int __init exynos4_init_cpuidle(void) 200static int __init exynos4_init_cpuidle(void)
64{ 201{
65 int i, max_cpuidle_state, cpu_id; 202 int i, max_cpuidle_state, cpu_id;
@@ -74,19 +211,25 @@ static int __init exynos4_init_cpuidle(void)
74 memcpy(&drv->states[i], &exynos4_cpuidle_set[i], 211 memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
75 sizeof(struct cpuidle_state)); 212 sizeof(struct cpuidle_state));
76 } 213 }
214 drv->safe_state_index = 0;
77 cpuidle_register_driver(&exynos4_idle_driver); 215 cpuidle_register_driver(&exynos4_idle_driver);
78 216
79 for_each_cpu(cpu_id, cpu_online_mask) { 217 for_each_cpu(cpu_id, cpu_online_mask) {
80 device = &per_cpu(exynos4_cpuidle_device, cpu_id); 218 device = &per_cpu(exynos4_cpuidle_device, cpu_id);
81 device->cpu = cpu_id; 219 device->cpu = cpu_id;
82 220
83 device->state_count = drv->state_count; 221 if (cpu_id == 0)
222 device->state_count = (sizeof(exynos4_cpuidle_set) /
223 sizeof(struct cpuidle_state));
224 else
225 device->state_count = 1; /* Support IDLE only */
84 226
85 if (cpuidle_register_device(device)) { 227 if (cpuidle_register_device(device)) {
86 printk(KERN_ERR "CPUidle register device failed\n,"); 228 printk(KERN_ERR "CPUidle register device failed\n,");
87 return -EIO; 229 return -EIO;
88 } 230 }
89 } 231 }
232
90 return 0; 233 return 0;
91} 234}
92device_initcall(exynos4_init_cpuidle); 235device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index c754a22a2bb..a8cd65fcc68 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -31,6 +31,10 @@
31#define EXYNOS4_PA_FIMC2 0x11820000 31#define EXYNOS4_PA_FIMC2 0x11820000
32#define EXYNOS4_PA_FIMC3 0x11830000 32#define EXYNOS4_PA_FIMC3 0x11830000
33 33
34#define EXYNOS4_PA_JPEG 0x11840000
35
36#define EXYNOS4_PA_G2D 0x12800000
37
34#define EXYNOS4_PA_I2S0 0x03830000 38#define EXYNOS4_PA_I2S0 0x03830000
35#define EXYNOS4_PA_I2S1 0xE3100000 39#define EXYNOS4_PA_I2S1 0xE3100000
36#define EXYNOS4_PA_I2S2 0xE2A00000 40#define EXYNOS4_PA_I2S2 0xE2A00000
@@ -57,6 +61,7 @@
57#define EXYNOS4_PA_KEYPAD 0x100A0000 61#define EXYNOS4_PA_KEYPAD 0x100A0000
58 62
59#define EXYNOS4_PA_DMC0 0x10400000 63#define EXYNOS4_PA_DMC0 0x10400000
64#define EXYNOS4_PA_DMC1 0x10410000
60 65
61#define EXYNOS4_PA_COMBINER 0x10440000 66#define EXYNOS4_PA_COMBINER 0x10440000
62 67
@@ -162,6 +167,8 @@
162#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 167#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
163#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 168#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
164#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 169#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
170#define S5P_PA_JPEG EXYNOS4_PA_JPEG
171#define S5P_PA_G2D EXYNOS4_PA_G2D
165#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 172#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
166#define S5P_PA_HDMI EXYNOS4_PA_HDMI 173#define S5P_PA_HDMI EXYNOS4_PA_HDMI
167#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY 174#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY
diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h
index 632dd563013..e76b7faba66 100644
--- a/arch/arm/mach-exynos/include/mach/pmu.h
+++ b/arch/arm/mach-exynos/include/mach/pmu.h
@@ -22,11 +22,13 @@ enum sys_powerdown {
22 NUM_SYS_POWERDOWN, 22 NUM_SYS_POWERDOWN,
23}; 23};
24 24
25extern unsigned long l2x0_regs_phys;
25struct exynos4_pmu_conf { 26struct exynos4_pmu_conf {
26 void __iomem *reg; 27 void __iomem *reg;
27 unsigned int val[NUM_SYS_POWERDOWN]; 28 unsigned int val[NUM_SYS_POWERDOWN];
28}; 29};
29 30
30extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); 31extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
32extern void s3c_cpu_resume(void);
31 33
32#endif /* __ASM_ARCH_PMU_H */ 34#endif /* __ASM_ARCH_PMU_H */
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index edc4b9488f2..e8a1caaf190 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -30,12 +30,13 @@
30#include <mach/regs-mct.h> 30#include <mach/regs-mct.h>
31#include <asm/mach/time.h> 31#include <asm/mach/time.h>
32 32
33#define TICK_BASE_CNT 1
34
33enum { 35enum {
34 MCT_INT_SPI, 36 MCT_INT_SPI,
35 MCT_INT_PPI 37 MCT_INT_PPI
36}; 38};
37 39
38static unsigned long clk_cnt_per_tick;
39static unsigned long clk_rate; 40static unsigned long clk_rate;
40static unsigned int mct_int_type; 41static unsigned int mct_int_type;
41 42
@@ -206,11 +207,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles,
206static void exynos4_comp_set_mode(enum clock_event_mode mode, 207static void exynos4_comp_set_mode(enum clock_event_mode mode,
207 struct clock_event_device *evt) 208 struct clock_event_device *evt)
208{ 209{
210 unsigned long cycles_per_jiffy;
209 exynos4_mct_comp0_stop(); 211 exynos4_mct_comp0_stop();
210 212
211 switch (mode) { 213 switch (mode) {
212 case CLOCK_EVT_MODE_PERIODIC: 214 case CLOCK_EVT_MODE_PERIODIC:
213 exynos4_mct_comp0_start(mode, clk_cnt_per_tick); 215 cycles_per_jiffy =
216 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
217 exynos4_mct_comp0_start(mode, cycles_per_jiffy);
214 break; 218 break;
215 219
216 case CLOCK_EVT_MODE_ONESHOT: 220 case CLOCK_EVT_MODE_ONESHOT:
@@ -249,9 +253,7 @@ static struct irqaction mct_comp_event_irq = {
249 253
250static void exynos4_clockevent_init(void) 254static void exynos4_clockevent_init(void)
251{ 255{
252 clk_cnt_per_tick = clk_rate / 2 / HZ; 256 clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
253
254 clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
255 mct_comp_device.max_delta_ns = 257 mct_comp_device.max_delta_ns =
256 clockevent_delta2ns(0xffffffff, &mct_comp_device); 258 clockevent_delta2ns(0xffffffff, &mct_comp_device);
257 mct_comp_device.min_delta_ns = 259 mct_comp_device.min_delta_ns =
@@ -315,12 +317,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
315 struct clock_event_device *evt) 317 struct clock_event_device *evt)
316{ 318{
317 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); 319 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
320 unsigned long cycles_per_jiffy;
318 321
319 exynos4_mct_tick_stop(mevt); 322 exynos4_mct_tick_stop(mevt);
320 323
321 switch (mode) { 324 switch (mode) {
322 case CLOCK_EVT_MODE_PERIODIC: 325 case CLOCK_EVT_MODE_PERIODIC:
323 exynos4_mct_tick_start(clk_cnt_per_tick, mevt); 326 cycles_per_jiffy =
327 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
328 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
324 break; 329 break;
325 330
326 case CLOCK_EVT_MODE_ONESHOT: 331 case CLOCK_EVT_MODE_ONESHOT:
@@ -394,7 +399,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
394 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 399 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
395 evt->rating = 450; 400 evt->rating = 450;
396 401
397 clockevents_calc_mult_shift(evt, clk_rate / 2, 5); 402 clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
398 evt->max_delta_ns = 403 evt->max_delta_ns =
399 clockevent_delta2ns(0x7fffffff, evt); 404 clockevent_delta2ns(0x7fffffff, evt);
400 evt->min_delta_ns = 405 evt->min_delta_ns =
@@ -402,7 +407,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
402 407
403 clockevents_register_device(evt); 408 clockevents_register_device(evt);
404 409
405 exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); 410 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
406 411
407 if (mct_int_type == MCT_INT_SPI) { 412 if (mct_int_type == MCT_INT_SPI) {
408 if (cpu == 0) { 413 if (cpu == 0) {
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index f105bd2b676..428cfeb5772 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = {
155 SAVE_ITEM(S5P_SROM_BC3), 155 SAVE_ITEM(S5P_SROM_BC3),
156}; 156};
157 157
158static struct sleep_save exynos4_l2cc_save[] = {
159 SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
160 SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
161 SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
162 SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
163 SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
164};
165 158
166/* For Cortex-A9 Diagnostic and Power control register */ 159/* For Cortex-A9 Diagnostic and Power control register */
167static unsigned int save_arm_register[2]; 160static unsigned int save_arm_register[2];
@@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void)
182 u32 tmp; 175 u32 tmp;
183 176
184 s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); 177 s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
185 s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
186 s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); 178 s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
187 s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); 179 s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
188 180
@@ -388,13 +380,6 @@ static void exynos4_pm_resume(void)
388 scu_enable(S5P_VA_SCU); 380 scu_enable(S5P_VA_SCU);
389#endif 381#endif
390 382
391#ifdef CONFIG_CACHE_L2X0
392 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
393 outer_inv_all();
394 /* enable L2X0*/
395 writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
396#endif
397
398early_wakeup: 383early_wakeup:
399 return; 384 return;
400} 385}
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index bb1684f9b68..808b055289b 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -110,7 +110,7 @@ static void __init highbank_timer_init(void)
110 110
111 highbank_clocks_init(); 111 highbank_clocks_init();
112 112
113 sp804_clocksource_init(timer_base + 0x20, "timer1"); 113 sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
114 sp804_clockevents_init(timer_base, irq, "timer0"); 114 sp804_clockevents_init(timer_base, irq, "timer0");
115 115
116 twd_local_timer_of_register(); 116 twd_local_timer_of_register();
diff --git a/arch/arm/mach-highbank/include/mach/memory.h b/arch/arm/mach-highbank/include/mach/memory.h
deleted file mode 100644
index 40a8c178f10..00000000000
--- a/arch/arm/mach-highbank/include/mach/memory.h
+++ /dev/null
@@ -1 +0,0 @@
1/* empty */
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 190d5700616..1ca9558723c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -8,8 +8,8 @@ obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
8obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o 8obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
9obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o 9obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
10 10
11obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o 11obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
12obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o 12obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
13 13
14obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o 14obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
15 15
diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c
index 5e2e7a84386..aa15c517d06 100644
--- a/arch/arm/mach-imx/cpu-imx5.c
+++ b/arch/arm/mach-imx/cpu-imx5.c
@@ -149,39 +149,3 @@ int mx50_revision(void)
149 return mx5_cpu_rev; 149 return mx5_cpu_rev;
150} 150}
151EXPORT_SYMBOL(mx50_revision); 151EXPORT_SYMBOL(mx50_revision);
152
153static int __init post_cpu_init(void)
154{
155 unsigned int reg;
156 void __iomem *base;
157
158 if (cpu_is_mx51() || cpu_is_mx53()) {
159 if (cpu_is_mx51())
160 base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
161 else
162 base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR);
163
164 __raw_writel(0x0, base + 0x40);
165 __raw_writel(0x0, base + 0x44);
166 __raw_writel(0x0, base + 0x48);
167 __raw_writel(0x0, base + 0x4C);
168 reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
169 __raw_writel(reg, base + 0x50);
170
171 if (cpu_is_mx51())
172 base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
173 else
174 base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR);
175
176 __raw_writel(0x0, base + 0x40);
177 __raw_writel(0x0, base + 0x44);
178 __raw_writel(0x0, base + 0x48);
179 __raw_writel(0x0, base + 0x4C);
180 reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
181 __raw_writel(reg, base + 0x50);
182 }
183
184 return 0;
185}
186
187postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-imx/crmregs-imx3.h b/arch/arm/mach-imx/crmregs-imx3.h
index d7691e2362c..53141273df4 100644
--- a/arch/arm/mach-imx/crmregs-imx3.h
+++ b/arch/arm/mach-imx/crmregs-imx3.h
@@ -77,6 +77,7 @@ MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR))
77#define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21) 77#define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21)
78#define MXC_CCM_CCMR_LPM_OFFSET 14 78#define MXC_CCM_CCMR_LPM_OFFSET 14
79#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14) 79#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14)
80#define MXC_CCM_CCMR_LPM_WAIT_MX35 (0x1 << 14)
80#define MXC_CCM_CCMR_FIRS_OFFSET 11 81#define MXC_CCM_CCMR_FIRS_OFFSET 11
81#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11) 82#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11)
82#define MXC_CCM_CCMR_UPE (1 << 9) 83#define MXC_CCM_CCMR_UPE (1 << 9)
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 07699196b46..f8ca96c354f 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -34,6 +34,8 @@ static void imx3_idle(void)
34{ 34{
35 unsigned long reg = 0; 35 unsigned long reg = 0;
36 36
37 mx3_cpu_lp_set(MX3_WAIT);
38
37 __asm__ __volatile__( 39 __asm__ __volatile__(
38 /* disable I and D cache */ 40 /* disable I and D cache */
39 "mrc p15, 0, %0, c1, c0, 0\n" 41 "mrc p15, 0, %0, c1, c0, 0\n"
@@ -177,6 +179,10 @@ void __init imx31_soc_init(void)
177 } 179 }
178 180
179 imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata); 181 imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
182
183 imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS1_BASE_ADDR));
184 imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS2_BASE_ADDR));
185
180 platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res, 186 platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
181 ARRAY_SIZE(imx31_audmux_res)); 187 ARRAY_SIZE(imx31_audmux_res));
182} 188}
@@ -267,6 +273,11 @@ void __init imx35_soc_init(void)
267 } 273 }
268 274
269 imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata); 275 imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
276
277 /* Setup AIPS registers */
278 imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS1_BASE_ADDR));
279 imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS2_BASE_ADDR));
280
270 /* i.mx35 has the i.mx31 type audmux */ 281 /* i.mx35 has the i.mx31 type audmux */
271 platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res, 282 platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res,
272 ARRAY_SIZE(imx35_audmux_res)); 283 ARRAY_SIZE(imx35_audmux_res));
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index dc7c4ed8153..51af9fa5694 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -201,6 +201,11 @@ void __init imx51_soc_init(void)
201 201
202 /* i.mx51 has the i.mx35 type sdma */ 202 /* i.mx51 has the i.mx35 type sdma */
203 imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); 203 imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
204
205 /* Setup AIPS registers */
206 imx_set_aips(MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR));
207 imx_set_aips(MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR));
208
204 /* i.mx51 has the i.mx31 type audmux */ 209 /* i.mx51 has the i.mx31 type audmux */
205 platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res, 210 platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res,
206 ARRAY_SIZE(imx51_audmux_res)); 211 ARRAY_SIZE(imx51_audmux_res));
@@ -219,6 +224,11 @@ void __init imx53_soc_init(void)
219 224
220 /* i.mx53 has the i.mx35 type sdma */ 225 /* i.mx53 has the i.mx35 type sdma */
221 imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata); 226 imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
227
228 /* Setup AIPS registers */
229 imx_set_aips(MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR));
230 imx_set_aips(MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR));
231
222 /* i.mx53 has the i.mx31 type audmux */ 232 /* i.mx53 has the i.mx31 type audmux */
223 platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res, 233 platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
224 ARRAY_SIZE(imx53_audmux_res)); 234 ARRAY_SIZE(imx53_audmux_res));
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
new file mode 100644
index 00000000000..b3752439632
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx3.c
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11#include <linux/io.h>
12#include <mach/common.h>
13#include <mach/hardware.h>
14#include <mach/devices-common.h>
15#include "crmregs-imx3.h"
16
17/*
18 * Set cpu low power mode before WFI instruction. This function is called
19 * mx3 because it can be used for mx31 and mx35.
20 * Currently only WAIT_MODE is supported.
21 */
22void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
23{
24 int reg = __raw_readl(MXC_CCM_CCMR);
25 reg &= ~MXC_CCM_CCMR_LPM_MASK;
26
27 switch (mode) {
28 case MX3_WAIT:
29 if (cpu_is_mx35())
30 reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
31 __raw_writel(reg, MXC_CCM_CCMR);
32 break;
33 default:
34 pr_err("Unknown cpu power mode: %d\n", mode);
35 return;
36 }
37}
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index e12e11231dc..293958beb50 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -223,7 +223,6 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
223{ 223{
224 u32 reg, bm_busy, div_max, d, f, div, frac; 224 u32 reg, bm_busy, div_max, d, f, div, frac;
225 unsigned long diff, parent_rate, calc_rate; 225 unsigned long diff, parent_rate, calc_rate;
226 int i;
227 226
228 parent_rate = clk_get_rate(clk->parent); 227 parent_rate = clk_get_rate(clk->parent);
229 228
@@ -275,14 +274,7 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
275 reg |= div << BP_CLKCTRL_CPU_DIV_CPU; 274 reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
276 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU); 275 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
277 276
278 for (i = 10000; i; i--) 277 mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
279 if (!(__raw_readl(CLKCTRL_BASE_ADDR +
280 HW_CLKCTRL_CPU) & bm_busy))
281 break;
282 if (!i) {
283 pr_err("%s: divider writing timeout\n", __func__);
284 return -ETIMEDOUT;
285 }
286 278
287 return 0; 279 return 0;
288} 280}
@@ -292,7 +284,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
292{ \ 284{ \
293 u32 reg, div_max, div; \ 285 u32 reg, div_max, div; \
294 unsigned long parent_rate; \ 286 unsigned long parent_rate; \
295 int i; \
296 \ 287 \
297 parent_rate = clk_get_rate(clk->parent); \ 288 parent_rate = clk_get_rate(clk->parent); \
298 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ 289 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
@@ -310,15 +301,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
310 } \ 301 } \
311 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ 302 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
312 \ 303 \
313 for (i = 10000; i; i--) \ 304 mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \
314 if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
315 HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
316 break; \
317 if (!i) { \
318 pr_err("%s: divider writing timeout\n", __func__); \
319 return -ETIMEDOUT; \
320 } \
321 \
322 return 0; \ 305 return 0; \
323} 306}
324 307
@@ -461,7 +444,7 @@ static struct clk_lookup lookups[] = {
461static int clk_misc_init(void) 444static int clk_misc_init(void)
462{ 445{
463 u32 reg; 446 u32 reg;
464 int i; 447 int ret;
465 448
466 /* Fix up parent per register setting */ 449 /* Fix up parent per register setting */
467 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ); 450 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -510,14 +493,7 @@ static int clk_misc_init(void)
510 reg |= 3 << BP_CLKCTRL_HBUS_DIV; 493 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
511 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS); 494 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
512 495
513 for (i = 10000; i; i--) 496 ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
514 if (!(__raw_readl(CLKCTRL_BASE_ADDR +
515 HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
516 break;
517 if (!i) {
518 pr_err("%s: divider writing timeout\n", __func__);
519 return -ETIMEDOUT;
520 }
521 497
522 /* Gate off cpu clock in WFI for power saving */ 498 /* Gate off cpu clock in WFI for power saving */
523 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, 499 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -532,7 +508,7 @@ static int clk_misc_init(void)
532 reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC; 508 reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
533 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); 509 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
534 510
535 return 0; 511 return ret;
536} 512}
537 513
538int __init mx23_clocks_init(void) 514int __init mx23_clocks_init(void)
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 5d68e415222..22ad12f6e4d 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -322,7 +322,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
322{ \ 322{ \
323 u32 reg, bm_busy, div_max, d, f, div, frac; \ 323 u32 reg, bm_busy, div_max, d, f, div, frac; \
324 unsigned long diff, parent_rate, calc_rate; \ 324 unsigned long diff, parent_rate, calc_rate; \
325 int i; \
326 \ 325 \
327 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ 326 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
328 bm_busy = BM_CLKCTRL_##dr##_BUSY; \ 327 bm_busy = BM_CLKCTRL_##dr##_BUSY; \
@@ -396,16 +395,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
396 } \ 395 } \
397 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ 396 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
398 \ 397 \
399 for (i = 10000; i; i--) \ 398 return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \
400 if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
401 HW_CLKCTRL_##dr) & bm_busy)) \
402 break; \
403 if (!i) { \
404 pr_err("%s: divider writing timeout\n", __func__); \
405 return -ETIMEDOUT; \
406 } \
407 \
408 return 0; \
409} 399}
410 400
411_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU) 401_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
@@ -421,7 +411,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
421{ \ 411{ \
422 u32 reg, div_max, div; \ 412 u32 reg, div_max, div; \
423 unsigned long parent_rate; \ 413 unsigned long parent_rate; \
424 int i; \
425 \ 414 \
426 parent_rate = clk_get_rate(clk->parent); \ 415 parent_rate = clk_get_rate(clk->parent); \
427 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ 416 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
@@ -439,16 +428,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
439 } \ 428 } \
440 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ 429 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
441 \ 430 \
442 for (i = 10000; i; i--) \ 431 return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
443 if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
444 HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
445 break; \
446 if (!i) { \
447 pr_err("%s: divider writing timeout\n", __func__); \
448 return -ETIMEDOUT; \
449 } \
450 \
451 return 0; \
452} 432}
453 433
454_CLK_SET_RATE1(xbus_clk, XBUS) 434_CLK_SET_RATE1(xbus_clk, XBUS)
@@ -461,7 +441,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
461 u32 reg; \ 441 u32 reg; \
462 u64 lrate; \ 442 u64 lrate; \
463 unsigned long parent_rate; \ 443 unsigned long parent_rate; \
464 int i; \
465 \ 444 \
466 parent_rate = clk_get_rate(clk->parent); \ 445 parent_rate = clk_get_rate(clk->parent); \
467 if (rate > parent_rate) \ 446 if (rate > parent_rate) \
@@ -477,18 +456,13 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
477 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \ 456 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
478 reg &= ~BM_CLKCTRL_##rs##_DIV; \ 457 reg &= ~BM_CLKCTRL_##rs##_DIV; \
479 reg |= div << BP_CLKCTRL_##rs##_DIV; \ 458 reg |= div << BP_CLKCTRL_##rs##_DIV; \
480 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \ 459 if (reg & (1 << clk->enable_shift)) { \
481 \ 460 pr_err("%s: clock is gated\n", __func__); \
482 for (i = 10000; i; i--) \ 461 return -EINVAL; \
483 if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
484 HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \
485 break; \
486 if (!i) { \
487 pr_err("%s: divider writing timeout\n", __func__); \
488 return -ETIMEDOUT; \
489 } \ 462 } \
463 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
490 \ 464 \
491 return 0; \ 465 return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
492} 466}
493 467
494_CLK_SET_RATE_SAIF(saif0_clk, SAIF0) 468_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
@@ -654,6 +628,8 @@ static struct clk_lookup lookups[] = {
654 _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk) 628 _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
655 _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk) 629 _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
656 _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk) 630 _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
631 _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
632 _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
657 _REGISTER_CLOCK("flexcan.0", NULL, can0_clk) 633 _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
658 _REGISTER_CLOCK("flexcan.1", NULL, can1_clk) 634 _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
659 _REGISTER_CLOCK(NULL, "usb0", usb0_clk) 635 _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -676,7 +652,7 @@ static struct clk_lookup lookups[] = {
676static int clk_misc_init(void) 652static int clk_misc_init(void)
677{ 653{
678 u32 reg; 654 u32 reg;
679 int i; 655 int ret;
680 656
681 /* Fix up parent per register setting */ 657 /* Fix up parent per register setting */
682 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ); 658 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -756,14 +732,7 @@ static int clk_misc_init(void)
756 reg |= 3 << BP_CLKCTRL_HBUS_DIV; 732 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
757 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS); 733 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
758 734
759 for (i = 10000; i; i--) 735 ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
760 if (!(__raw_readl(CLKCTRL_BASE_ADDR +
761 HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
762 break;
763 if (!i) {
764 pr_err("%s: divider writing timeout\n", __func__);
765 return -ETIMEDOUT;
766 }
767 736
768 /* Gate off cpu clock in WFI for power saving */ 737 /* Gate off cpu clock in WFI for power saving */
769 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, 738 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -790,7 +759,7 @@ static int clk_misc_init(void)
790 reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC; 759 reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
791 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); 760 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
792 761
793 return 0; 762 return ret;
794} 763}
795 764
796int __init mx28_clocks_init(void) 765int __init mx28_clocks_init(void)
@@ -803,6 +772,8 @@ int __init mx28_clocks_init(void)
803 */ 772 */
804 clk_set_parent(&ssp0_clk, &ref_io0_clk); 773 clk_set_parent(&ssp0_clk, &ref_io0_clk);
805 clk_set_parent(&ssp1_clk, &ref_io0_clk); 774 clk_set_parent(&ssp1_clk, &ref_io0_clk);
775 clk_set_parent(&ssp2_clk, &ref_io1_clk);
776 clk_set_parent(&ssp3_clk, &ref_io1_clk);
806 777
807 clk_prepare_enable(&cpu_clk); 778 clk_prepare_enable(&cpu_clk);
808 clk_prepare_enable(&hbus_clk); 779 clk_prepare_enable(&hbus_clk);
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
index 382dacbeca2..bef9d923f54 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -41,6 +41,8 @@ const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
41const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = { 41const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
42 mxs_mxs_mmc_data_entry(MX28, 0, 0), 42 mxs_mxs_mmc_data_entry(MX28, 0, 0),
43 mxs_mxs_mmc_data_entry(MX28, 1, 1), 43 mxs_mxs_mmc_data_entry(MX28, 1, 1),
44 mxs_mxs_mmc_data_entry(MX28, 2, 2),
45 mxs_mxs_mmc_data_entry(MX28, 3, 3),
44}; 46};
45#endif 47#endif
46 48
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index e1237ab2586..c50c3ea28a9 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -31,4 +31,6 @@ extern void mx28_init_irq(void);
31 31
32extern void icoll_init_irq(void); 32extern void icoll_init_irq(void);
33 33
34extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);
35
34#endif /* __MACH_MXS_COMMON_H__ */ 36#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 54f91ad1c96..7aa5ac5d78b 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -37,6 +37,8 @@
37#define MXS_MODULE_CLKGATE (1 << 30) 37#define MXS_MODULE_CLKGATE (1 << 30)
38#define MXS_MODULE_SFTRST (1 << 31) 38#define MXS_MODULE_SFTRST (1 << 31)
39 39
40#define CLKCTRL_TIMEOUT 10 /* 10 ms */
41
40static void __iomem *mxs_clkctrl_reset_addr; 42static void __iomem *mxs_clkctrl_reset_addr;
41 43
42/* 44/*
@@ -137,3 +139,17 @@ error:
137 return -ETIMEDOUT; 139 return -ETIMEDOUT;
138} 140}
139EXPORT_SYMBOL(mxs_reset_block); 141EXPORT_SYMBOL(mxs_reset_block);
142
143int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
144{
145 unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
146 while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
147 + reg_offset) & mask) {
148 if (time_after(jiffies, timeout)) {
149 pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
150 return -ETIMEDOUT;
151 }
152 }
153
154 return 0;
155}
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 613e2c1eeb2..0e79b7bc6aa 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -29,7 +29,7 @@
29#include "control.h" 29#include "control.h"
30 30
31static unsigned int omap_revision; 31static unsigned int omap_revision;
32 32static const char *cpu_rev;
33u32 omap_features; 33u32 omap_features;
34 34
35unsigned int omap_rev(void) 35unsigned int omap_rev(void)
@@ -114,7 +114,7 @@ void omap_get_die_id(struct omap_die_id *odi)
114 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); 114 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
115} 115}
116 116
117static void __init omap24xx_check_revision(void) 117void __init omap2xxx_check_revision(void)
118{ 118{
119 int i, j; 119 int i, j;
120 u32 idcode, prod_id; 120 u32 idcode, prod_id;
@@ -168,13 +168,63 @@ static void __init omap24xx_check_revision(void)
168 pr_info("\n"); 168 pr_info("\n");
169} 169}
170 170
171#define OMAP3_SHOW_FEATURE(feat) \
172 if (omap3_has_ ##feat()) \
173 printk(#feat" ");
174
175static void __init omap3_cpuinfo(void)
176{
177 const char *cpu_name;
178
179 /*
180 * OMAP3430 and OMAP3530 are assumed to be same.
181 *
182 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
183 * on available features. Upon detection, update the CPU id
184 * and CPU class bits.
185 */
186 if (cpu_is_omap3630()) {
187 cpu_name = "OMAP3630";
188 } else if (cpu_is_omap3517()) {
189 /* AM35xx devices */
190 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
191 } else if (cpu_is_ti816x()) {
192 cpu_name = "TI816X";
193 } else if (cpu_is_am335x()) {
194 cpu_name = "AM335X";
195 } else if (cpu_is_ti814x()) {
196 cpu_name = "TI814X";
197 } else if (omap3_has_iva() && omap3_has_sgx()) {
198 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
199 cpu_name = "OMAP3430/3530";
200 } else if (omap3_has_iva()) {
201 cpu_name = "OMAP3525";
202 } else if (omap3_has_sgx()) {
203 cpu_name = "OMAP3515";
204 } else {
205 cpu_name = "OMAP3503";
206 }
207
208 /* Print verbose information */
209 pr_info("%s ES%s (", cpu_name, cpu_rev);
210
211 OMAP3_SHOW_FEATURE(l2cache);
212 OMAP3_SHOW_FEATURE(iva);
213 OMAP3_SHOW_FEATURE(sgx);
214 OMAP3_SHOW_FEATURE(neon);
215 OMAP3_SHOW_FEATURE(isp);
216 OMAP3_SHOW_FEATURE(192mhz_clk);
217
218 printk(")\n");
219}
220
171#define OMAP3_CHECK_FEATURE(status,feat) \ 221#define OMAP3_CHECK_FEATURE(status,feat) \
172 if (((status & OMAP3_ ##feat## _MASK) \ 222 if (((status & OMAP3_ ##feat## _MASK) \
173 >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ 223 >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \
174 omap_features |= OMAP3_HAS_ ##feat; \ 224 omap_features |= OMAP3_HAS_ ##feat; \
175 } 225 }
176 226
177static void __init omap3_check_features(void) 227void __init omap3xxx_check_features(void)
178{ 228{
179 u32 status; 229 u32 status;
180 230
@@ -201,9 +251,11 @@ static void __init omap3_check_features(void)
201 * TODO: Get additional info (where applicable) 251 * TODO: Get additional info (where applicable)
202 * e.g. Size of L2 cache. 252 * e.g. Size of L2 cache.
203 */ 253 */
254
255 omap3_cpuinfo();
204} 256}
205 257
206static void __init omap4_check_features(void) 258void __init omap4xxx_check_features(void)
207{ 259{
208 u32 si_type; 260 u32 si_type;
209 261
@@ -228,12 +280,13 @@ static void __init omap4_check_features(void)
228 } 280 }
229} 281}
230 282
231static void __init ti81xx_check_features(void) 283void __init ti81xx_check_features(void)
232{ 284{
233 omap_features = OMAP3_HAS_NEON; 285 omap_features = OMAP3_HAS_NEON;
286 omap3_cpuinfo();
234} 287}
235 288
236static void __init omap3_check_revision(const char **cpu_rev) 289void __init omap3xxx_check_revision(void)
237{ 290{
238 u32 cpuid, idcode; 291 u32 cpuid, idcode;
239 u16 hawkeye; 292 u16 hawkeye;
@@ -247,7 +300,7 @@ static void __init omap3_check_revision(const char **cpu_rev)
247 cpuid = read_cpuid(CPUID_ID); 300 cpuid = read_cpuid(CPUID_ID);
248 if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) { 301 if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
249 omap_revision = OMAP3430_REV_ES1_0; 302 omap_revision = OMAP3430_REV_ES1_0;
250 *cpu_rev = "1.0"; 303 cpu_rev = "1.0";
251 return; 304 return;
252 } 305 }
253 306
@@ -268,26 +321,26 @@ static void __init omap3_check_revision(const char **cpu_rev)
268 case 0: /* Take care of early samples */ 321 case 0: /* Take care of early samples */
269 case 1: 322 case 1:
270 omap_revision = OMAP3430_REV_ES2_0; 323 omap_revision = OMAP3430_REV_ES2_0;
271 *cpu_rev = "2.0"; 324 cpu_rev = "2.0";
272 break; 325 break;
273 case 2: 326 case 2:
274 omap_revision = OMAP3430_REV_ES2_1; 327 omap_revision = OMAP3430_REV_ES2_1;
275 *cpu_rev = "2.1"; 328 cpu_rev = "2.1";
276 break; 329 break;
277 case 3: 330 case 3:
278 omap_revision = OMAP3430_REV_ES3_0; 331 omap_revision = OMAP3430_REV_ES3_0;
279 *cpu_rev = "3.0"; 332 cpu_rev = "3.0";
280 break; 333 break;
281 case 4: 334 case 4:
282 omap_revision = OMAP3430_REV_ES3_1; 335 omap_revision = OMAP3430_REV_ES3_1;
283 *cpu_rev = "3.1"; 336 cpu_rev = "3.1";
284 break; 337 break;
285 case 7: 338 case 7:
286 /* FALLTHROUGH */ 339 /* FALLTHROUGH */
287 default: 340 default:
288 /* Use the latest known revision as default */ 341 /* Use the latest known revision as default */
289 omap_revision = OMAP3430_REV_ES3_1_2; 342 omap_revision = OMAP3430_REV_ES3_1_2;
290 *cpu_rev = "3.1.2"; 343 cpu_rev = "3.1.2";
291 } 344 }
292 break; 345 break;
293 case 0xb868: 346 case 0xb868:
@@ -300,13 +353,13 @@ static void __init omap3_check_revision(const char **cpu_rev)
300 switch (rev) { 353 switch (rev) {
301 case 0: 354 case 0:
302 omap_revision = OMAP3517_REV_ES1_0; 355 omap_revision = OMAP3517_REV_ES1_0;
303 *cpu_rev = "1.0"; 356 cpu_rev = "1.0";
304 break; 357 break;
305 case 1: 358 case 1:
306 /* FALLTHROUGH */ 359 /* FALLTHROUGH */
307 default: 360 default:
308 omap_revision = OMAP3517_REV_ES1_1; 361 omap_revision = OMAP3517_REV_ES1_1;
309 *cpu_rev = "1.1"; 362 cpu_rev = "1.1";
310 } 363 }
311 break; 364 break;
312 case 0xb891: 365 case 0xb891:
@@ -315,36 +368,36 @@ static void __init omap3_check_revision(const char **cpu_rev)
315 switch(rev) { 368 switch(rev) {
316 case 0: /* Take care of early samples */ 369 case 0: /* Take care of early samples */
317 omap_revision = OMAP3630_REV_ES1_0; 370 omap_revision = OMAP3630_REV_ES1_0;
318 *cpu_rev = "1.0"; 371 cpu_rev = "1.0";
319 break; 372 break;
320 case 1: 373 case 1:
321 omap_revision = OMAP3630_REV_ES1_1; 374 omap_revision = OMAP3630_REV_ES1_1;
322 *cpu_rev = "1.1"; 375 cpu_rev = "1.1";
323 break; 376 break;
324 case 2: 377 case 2:
325 /* FALLTHROUGH */ 378 /* FALLTHROUGH */
326 default: 379 default:
327 omap_revision = OMAP3630_REV_ES1_2; 380 omap_revision = OMAP3630_REV_ES1_2;
328 *cpu_rev = "1.2"; 381 cpu_rev = "1.2";
329 } 382 }
330 break; 383 break;
331 case 0xb81e: 384 case 0xb81e:
332 switch (rev) { 385 switch (rev) {
333 case 0: 386 case 0:
334 omap_revision = TI8168_REV_ES1_0; 387 omap_revision = TI8168_REV_ES1_0;
335 *cpu_rev = "1.0"; 388 cpu_rev = "1.0";
336 break; 389 break;
337 case 1: 390 case 1:
338 /* FALLTHROUGH */ 391 /* FALLTHROUGH */
339 default: 392 default:
340 omap_revision = TI8168_REV_ES1_1; 393 omap_revision = TI8168_REV_ES1_1;
341 *cpu_rev = "1.1"; 394 cpu_rev = "1.1";
342 break; 395 break;
343 } 396 }
344 break; 397 break;
345 case 0xb944: 398 case 0xb944:
346 omap_revision = AM335X_REV_ES1_0; 399 omap_revision = AM335X_REV_ES1_0;
347 *cpu_rev = "1.0"; 400 cpu_rev = "1.0";
348 break; 401 break;
349 case 0xb8f2: 402 case 0xb8f2:
350 switch (rev) { 403 switch (rev) {
@@ -352,29 +405,29 @@ static void __init omap3_check_revision(const char **cpu_rev)
352 /* FALLTHROUGH */ 405 /* FALLTHROUGH */
353 case 1: 406 case 1:
354 omap_revision = TI8148_REV_ES1_0; 407 omap_revision = TI8148_REV_ES1_0;
355 *cpu_rev = "1.0"; 408 cpu_rev = "1.0";
356 break; 409 break;
357 case 2: 410 case 2:
358 omap_revision = TI8148_REV_ES2_0; 411 omap_revision = TI8148_REV_ES2_0;
359 *cpu_rev = "2.0"; 412 cpu_rev = "2.0";
360 break; 413 break;
361 case 3: 414 case 3:
362 /* FALLTHROUGH */ 415 /* FALLTHROUGH */
363 default: 416 default:
364 omap_revision = TI8148_REV_ES2_1; 417 omap_revision = TI8148_REV_ES2_1;
365 *cpu_rev = "2.1"; 418 cpu_rev = "2.1";
366 break; 419 break;
367 } 420 }
368 break; 421 break;
369 default: 422 default:
370 /* Unknown default to latest silicon rev as default */ 423 /* Unknown default to latest silicon rev as default */
371 omap_revision = OMAP3630_REV_ES1_2; 424 omap_revision = OMAP3630_REV_ES1_2;
372 *cpu_rev = "1.2"; 425 cpu_rev = "1.2";
373 pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); 426 pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n");
374 } 427 }
375} 428}
376 429
377static void __init omap4_check_revision(void) 430void __init omap4xxx_check_revision(void)
378{ 431{
379 u32 idcode; 432 u32 idcode;
380 u16 hawkeye; 433 u16 hawkeye;
@@ -447,89 +500,6 @@ static void __init omap4_check_revision(void)
447 ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); 500 ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf));
448} 501}
449 502
450#define OMAP3_SHOW_FEATURE(feat) \
451 if (omap3_has_ ##feat()) \
452 printk(#feat" ");
453
454static void __init omap3_cpuinfo(const char *cpu_rev)
455{
456 const char *cpu_name;
457
458 /*
459 * OMAP3430 and OMAP3530 are assumed to be same.
460 *
461 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
462 * on available features. Upon detection, update the CPU id
463 * and CPU class bits.
464 */
465 if (cpu_is_omap3630()) {
466 cpu_name = "OMAP3630";
467 } else if (cpu_is_omap3517()) {
468 /* AM35xx devices */
469 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
470 } else if (cpu_is_ti816x()) {
471 cpu_name = "TI816X";
472 } else if (cpu_is_am335x()) {
473 cpu_name = "AM335X";
474 } else if (cpu_is_ti814x()) {
475 cpu_name = "TI814X";
476 } else if (omap3_has_iva() && omap3_has_sgx()) {
477 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
478 cpu_name = "OMAP3430/3530";
479 } else if (omap3_has_iva()) {
480 cpu_name = "OMAP3525";
481 } else if (omap3_has_sgx()) {
482 cpu_name = "OMAP3515";
483 } else {
484 cpu_name = "OMAP3503";
485 }
486
487 /* Print verbose information */
488 pr_info("%s ES%s (", cpu_name, cpu_rev);
489
490 OMAP3_SHOW_FEATURE(l2cache);
491 OMAP3_SHOW_FEATURE(iva);
492 OMAP3_SHOW_FEATURE(sgx);
493 OMAP3_SHOW_FEATURE(neon);
494 OMAP3_SHOW_FEATURE(isp);
495 OMAP3_SHOW_FEATURE(192mhz_clk);
496
497 printk(")\n");
498}
499
500/*
501 * Try to detect the exact revision of the omap we're running on
502 */
503void __init omap2_check_revision(void)
504{
505 const char *cpu_rev;
506
507 /*
508 * At this point we have an idea about the processor revision set
509 * earlier with omap2_set_globals_tap().
510 */
511 if (cpu_is_omap24xx()) {
512 omap24xx_check_revision();
513 } else if (cpu_is_omap34xx()) {
514 omap3_check_revision(&cpu_rev);
515
516 /* TI81XX doesn't have feature register */
517 if (!cpu_is_ti81xx())
518 omap3_check_features();
519 else
520 ti81xx_check_features();
521
522 omap3_cpuinfo(cpu_rev);
523 return;
524 } else if (cpu_is_omap44xx()) {
525 omap4_check_revision();
526 omap4_check_features();
527 return;
528 } else {
529 pr_err("OMAP revision unknown, please fix!\n");
530 }
531}
532
533/* 503/*
534 * Set up things for map_io and processor detection later on. Gets called 504 * Set up things for map_io and processor detection later on. Gets called
535 * pretty much first thing from board init. For multi-omap, this gets 505 * pretty much first thing from board init. For multi-omap, this gets
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index cd47a71297b..065bd768987 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -348,7 +348,6 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
348 348
349static void __init omap_common_init_early(void) 349static void __init omap_common_init_early(void)
350{ 350{
351 omap2_check_revision();
352 omap_init_consistent_dma_size(); 351 omap_init_consistent_dma_size();
353} 352}
354 353
@@ -389,6 +388,7 @@ static void __init omap_hwmod_init_postsetup(void)
389void __init omap2420_init_early(void) 388void __init omap2420_init_early(void)
390{ 389{
391 omap2_set_globals_242x(); 390 omap2_set_globals_242x();
391 omap2xxx_check_revision();
392 omap_common_init_early(); 392 omap_common_init_early();
393 omap2xxx_voltagedomains_init(); 393 omap2xxx_voltagedomains_init();
394 omap242x_powerdomains_init(); 394 omap242x_powerdomains_init();
@@ -403,6 +403,7 @@ void __init omap2420_init_early(void)
403void __init omap2430_init_early(void) 403void __init omap2430_init_early(void)
404{ 404{
405 omap2_set_globals_243x(); 405 omap2_set_globals_243x();
406 omap2xxx_check_revision();
406 omap_common_init_early(); 407 omap_common_init_early();
407 omap2xxx_voltagedomains_init(); 408 omap2xxx_voltagedomains_init();
408 omap243x_powerdomains_init(); 409 omap243x_powerdomains_init();
@@ -421,6 +422,8 @@ void __init omap2430_init_early(void)
421void __init omap3_init_early(void) 422void __init omap3_init_early(void)
422{ 423{
423 omap2_set_globals_3xxx(); 424 omap2_set_globals_3xxx();
425 omap3xxx_check_revision();
426 omap3xxx_check_features();
424 omap_common_init_early(); 427 omap_common_init_early();
425 omap3xxx_voltagedomains_init(); 428 omap3xxx_voltagedomains_init();
426 omap3xxx_powerdomains_init(); 429 omap3xxx_powerdomains_init();
@@ -453,6 +456,8 @@ void __init am35xx_init_early(void)
453void __init ti81xx_init_early(void) 456void __init ti81xx_init_early(void)
454{ 457{
455 omap2_set_globals_ti81xx(); 458 omap2_set_globals_ti81xx();
459 omap3xxx_check_revision();
460 ti81xx_check_features();
456 omap_common_init_early(); 461 omap_common_init_early();
457 omap3xxx_voltagedomains_init(); 462 omap3xxx_voltagedomains_init();
458 omap3xxx_powerdomains_init(); 463 omap3xxx_powerdomains_init();
@@ -467,6 +472,8 @@ void __init ti81xx_init_early(void)
467void __init omap4430_init_early(void) 472void __init omap4430_init_early(void)
468{ 473{
469 omap2_set_globals_443x(); 474 omap2_set_globals_443x();
475 omap4xxx_check_revision();
476 omap4xxx_check_features();
470 omap_common_init_early(); 477 omap_common_init_early();
471 omap44xx_voltagedomains_init(); 478 omap44xx_voltagedomains_init();
472 omap44xx_powerdomains_init(); 479 omap44xx_powerdomains_init();
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index dd20c66cd70..326ea3a9872 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -83,6 +83,11 @@ config S3C64XX_SETUP_SPI
83 help 83 help
84 Common setup code for SPI GPIO configurations 84 Common setup code for SPI GPIO configurations
85 85
86config S3C64XX_SETUP_USB_PHY
87 bool
88 help
89 Common setup code for USB PHY controller
90
86# S36400 Macchine support 91# S36400 Macchine support
87 92
88config MACH_SMDK6400 93config MACH_SMDK6400
@@ -157,6 +162,7 @@ config MACH_SMDK6410
157 select S3C64XX_SETUP_IDE 162 select S3C64XX_SETUP_IDE
158 select S3C64XX_SETUP_FB_24BPP 163 select S3C64XX_SETUP_FB_24BPP
159 select S3C64XX_SETUP_KEYPAD 164 select S3C64XX_SETUP_KEYPAD
165 select S3C64XX_SETUP_USB_PHY
160 help 166 help
161 Machine support for the Samsung SMDK6410 167 Machine support for the Samsung SMDK6410
162 168
@@ -256,6 +262,7 @@ config MACH_SMARTQ
256 select S3C_DEV_USB_HOST 262 select S3C_DEV_USB_HOST
257 select S3C64XX_SETUP_SDHCI 263 select S3C64XX_SETUP_SDHCI
258 select S3C64XX_SETUP_FB_24BPP 264 select S3C64XX_SETUP_FB_24BPP
265 select S3C64XX_SETUP_USB_PHY
259 select SAMSUNG_DEV_ADC 266 select SAMSUNG_DEV_ADC
260 select SAMSUNG_DEV_PWM 267 select SAMSUNG_DEV_PWM
261 select SAMSUNG_DEV_TS 268 select SAMSUNG_DEV_TS
@@ -283,6 +290,7 @@ config MACH_WLF_CRAGG_6410
283 select S3C64XX_SETUP_FB_24BPP 290 select S3C64XX_SETUP_FB_24BPP
284 select S3C64XX_SETUP_KEYPAD 291 select S3C64XX_SETUP_KEYPAD
285 select S3C64XX_SETUP_SPI 292 select S3C64XX_SETUP_SPI
293 select S3C64XX_SETUP_USB_PHY
286 select SAMSUNG_DEV_ADC 294 select SAMSUNG_DEV_ADC
287 select SAMSUNG_DEV_KEYPAD 295 select SAMSUNG_DEV_KEYPAD
288 select S3C_DEV_USB_HOST 296 select S3C_DEV_USB_HOST
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 1822ac2eba3..f9ce1dc28ce 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
22# PM 22# PM
23 23
24obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o 24obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
25obj-$(CONFIG_CPU_IDLE) += cpuidle.o
25 26
26# DMA support 27# DMA support
27 28
@@ -42,6 +43,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
42obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o 43obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
43obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 44obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
44obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o 45obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
46obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o
45 47
46# Machine support 48# Machine support
47 49
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index aebbcc291b4..52f079a691c 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -207,6 +207,15 @@ static struct clk init_clocks_off[] = {
207 .enable = s3c64xx_sclk_ctrl, 207 .enable = s3c64xx_sclk_ctrl,
208 .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, 208 .ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
209 }, { 209 }, {
210 .name = "ac97",
211 .parent = &clk_p,
212 .ctrlbit = S3C_CLKCON_PCLK_AC97,
213 }, {
214 .name = "cfcon",
215 .parent = &clk_h,
216 .enable = s3c64xx_hclk_ctrl,
217 .ctrlbit = S3C_CLKCON_HCLK_IHOST,
218 }, {
210 .name = "dma0", 219 .name = "dma0",
211 .parent = &clk_h, 220 .parent = &clk_h,
212 .enable = s3c64xx_hclk_ctrl, 221 .enable = s3c64xx_hclk_ctrl,
@@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = {
216 .parent = &clk_h, 225 .parent = &clk_h,
217 .enable = s3c64xx_hclk_ctrl, 226 .enable = s3c64xx_hclk_ctrl,
218 .ctrlbit = S3C_CLKCON_HCLK_DMA1, 227 .ctrlbit = S3C_CLKCON_HCLK_DMA1,
228 }, {
229 .name = "3dse",
230 .parent = &clk_h,
231 .enable = s3c64xx_hclk_ctrl,
232 .ctrlbit = S3C_CLKCON_HCLK_3DSE,
233 }, {
234 .name = "hclk_secur",
235 .parent = &clk_h,
236 .enable = s3c64xx_hclk_ctrl,
237 .ctrlbit = S3C_CLKCON_HCLK_SECUR,
238 }, {
239 .name = "sdma1",
240 .parent = &clk_h,
241 .enable = s3c64xx_hclk_ctrl,
242 .ctrlbit = S3C_CLKCON_HCLK_SDMA1,
243 }, {
244 .name = "sdma0",
245 .parent = &clk_h,
246 .enable = s3c64xx_hclk_ctrl,
247 .ctrlbit = S3C_CLKCON_HCLK_SDMA0,
248 }, {
249 .name = "hclk_jpeg",
250 .parent = &clk_h,
251 .enable = s3c64xx_hclk_ctrl,
252 .ctrlbit = S3C_CLKCON_HCLK_JPEG,
253 }, {
254 .name = "camif",
255 .parent = &clk_h,
256 .enable = s3c64xx_hclk_ctrl,
257 .ctrlbit = S3C_CLKCON_HCLK_CAMIF,
258 }, {
259 .name = "hclk_scaler",
260 .parent = &clk_h,
261 .enable = s3c64xx_hclk_ctrl,
262 .ctrlbit = S3C_CLKCON_HCLK_SCALER,
263 }, {
264 .name = "2d",
265 .parent = &clk_h,
266 .enable = s3c64xx_hclk_ctrl,
267 .ctrlbit = S3C_CLKCON_HCLK_2D,
268 }, {
269 .name = "tv",
270 .parent = &clk_h,
271 .enable = s3c64xx_hclk_ctrl,
272 .ctrlbit = S3C_CLKCON_HCLK_TV,
273 }, {
274 .name = "post0",
275 .parent = &clk_h,
276 .enable = s3c64xx_hclk_ctrl,
277 .ctrlbit = S3C_CLKCON_HCLK_POST0,
278 }, {
279 .name = "rot",
280 .parent = &clk_h,
281 .enable = s3c64xx_hclk_ctrl,
282 .ctrlbit = S3C_CLKCON_HCLK_ROT,
283 }, {
284 .name = "hclk_mfc",
285 .parent = &clk_h,
286 .enable = s3c64xx_hclk_ctrl,
287 .ctrlbit = S3C_CLKCON_HCLK_MFC,
288 }, {
289 .name = "pclk_mfc",
290 .parent = &clk_p,
291 .enable = s3c64xx_pclk_ctrl,
292 .ctrlbit = S3C_CLKCON_PCLK_MFC,
293 }, {
294 .name = "dac27",
295 .enable = s3c64xx_sclk_ctrl,
296 .ctrlbit = S3C_CLKCON_SCLK_DAC27,
297 }, {
298 .name = "tv27",
299 .enable = s3c64xx_sclk_ctrl,
300 .ctrlbit = S3C_CLKCON_SCLK_TV27,
301 }, {
302 .name = "scaler27",
303 .enable = s3c64xx_sclk_ctrl,
304 .ctrlbit = S3C_CLKCON_SCLK_SCALER27,
305 }, {
306 .name = "sclk_scaler",
307 .enable = s3c64xx_sclk_ctrl,
308 .ctrlbit = S3C_CLKCON_SCLK_SCALER,
309 }, {
310 .name = "post0_27",
311 .enable = s3c64xx_sclk_ctrl,
312 .ctrlbit = S3C_CLKCON_SCLK_POST0_27,
313 }, {
314 .name = "secur",
315 .enable = s3c64xx_sclk_ctrl,
316 .ctrlbit = S3C_CLKCON_SCLK_SECUR,
317 }, {
318 .name = "sclk_mfc",
319 .enable = s3c64xx_sclk_ctrl,
320 .ctrlbit = S3C_CLKCON_SCLK_MFC,
321 }, {
322 .name = "cam",
323 .enable = s3c64xx_sclk_ctrl,
324 .ctrlbit = S3C_CLKCON_SCLK_CAM,
325 }, {
326 .name = "sclk_jpeg",
327 .enable = s3c64xx_sclk_ctrl,
328 .ctrlbit = S3C_CLKCON_SCLK_JPEG,
219 }, 329 },
220}; 330};
221 331
@@ -289,16 +399,7 @@ static struct clk init_clocks[] = {
289 .name = "watchdog", 399 .name = "watchdog",
290 .parent = &clk_p, 400 .parent = &clk_p,
291 .ctrlbit = S3C_CLKCON_PCLK_WDT, 401 .ctrlbit = S3C_CLKCON_PCLK_WDT,
292 }, { 402 },
293 .name = "ac97",
294 .parent = &clk_p,
295 .ctrlbit = S3C_CLKCON_PCLK_AC97,
296 }, {
297 .name = "cfcon",
298 .parent = &clk_h,
299 .enable = s3c64xx_hclk_ctrl,
300 .ctrlbit = S3C_CLKCON_HCLK_IHOST,
301 }
302}; 403};
303 404
304static struct clk clk_hsmmc0 = { 405static struct clk clk_hsmmc0 = {
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
new file mode 100644
index 00000000000..179460f38db
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -0,0 +1,91 @@
1/* linux/arch/arm/mach-s3c64xx/cpuidle.c
2 *
3 * Copyright (c) 2011 Wolfson Microelectronics, plc
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/cpuidle.h>
15#include <linux/io.h>
16#include <linux/export.h>
17#include <linux/time.h>
18
19#include <asm/proc-fns.h>
20
21#include <mach/map.h>
22
23#include <mach/regs-sys.h>
24#include <mach/regs-syscon-power.h>
25
26static int s3c64xx_enter_idle(struct cpuidle_device *dev,
27 struct cpuidle_driver *drv,
28 int index)
29{
30 struct timeval before, after;
31 unsigned long tmp;
32 int idle_time;
33
34 local_irq_disable();
35 do_gettimeofday(&before);
36
37 /* Setup PWRCFG to enter idle mode */
38 tmp = __raw_readl(S3C64XX_PWR_CFG);
39 tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
40 tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
41 __raw_writel(tmp, S3C64XX_PWR_CFG);
42
43 cpu_do_idle();
44
45 do_gettimeofday(&after);
46 local_irq_enable();
47 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
48 (after.tv_usec - before.tv_usec);
49
50 dev->last_residency = idle_time;
51 return index;
52}
53
54static struct cpuidle_state s3c64xx_cpuidle_set[] = {
55 [0] = {
56 .enter = s3c64xx_enter_idle,
57 .exit_latency = 1,
58 .target_residency = 1,
59 .flags = CPUIDLE_FLAG_TIME_VALID,
60 .name = "IDLE",
61 .desc = "System active, ARM gated",
62 },
63};
64
65static struct cpuidle_driver s3c64xx_cpuidle_driver = {
66 .name = "s3c64xx_cpuidle",
67 .owner = THIS_MODULE,
68 .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set),
69};
70
71static struct cpuidle_device s3c64xx_cpuidle_device = {
72 .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set),
73};
74
75static int __init s3c64xx_init_cpuidle(void)
76{
77 int ret;
78
79 memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
80 sizeof(s3c64xx_cpuidle_set));
81 cpuidle_register_driver(&s3c64xx_cpuidle_driver);
82
83 ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
84 if (ret) {
85 pr_err("Failed to register cpuidle device: %d\n", ret);
86 return ret;
87 }
88
89 return 0;
90}
91device_initcall(s3c64xx_init_cpuidle);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 8077f650eb0..3b56bd9cb88 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -59,6 +59,7 @@
59#include <plat/sdhci.h> 59#include <plat/sdhci.h>
60#include <plat/gpio-cfg.h> 60#include <plat/gpio-cfg.h>
61#include <plat/s3c64xx-spi.h> 61#include <plat/s3c64xx-spi.h>
62#include <plat/udc-hs.h>
62 63
63#include <plat/keypad.h> 64#include <plat/keypad.h>
64#include <plat/clock.h> 65#include <plat/clock.h>
@@ -698,6 +699,8 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
698 .cfg_gpio = crag6410_cfg_sdhci0, 699 .cfg_gpio = crag6410_cfg_sdhci0,
699}; 700};
700 701
702static struct s3c_hsotg_plat crag6410_hsotg_pdata;
703
701static void __init crag6410_machine_init(void) 704static void __init crag6410_machine_init(void)
702{ 705{
703 /* Open drain IRQs need pullups */ 706 /* Open drain IRQs need pullups */
@@ -722,6 +725,7 @@ static void __init crag6410_machine_init(void)
722 s3c_i2c0_set_platdata(&i2c0_pdata); 725 s3c_i2c0_set_platdata(&i2c0_pdata);
723 s3c_i2c1_set_platdata(&i2c1_pdata); 726 s3c_i2c1_set_platdata(&i2c1_pdata);
724 s3c_fb_set_platdata(&crag6410_lcd_pdata); 727 s3c_fb_set_platdata(&crag6410_lcd_pdata);
728 s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
725 729
726 i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); 730 i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
727 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); 731 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index ce31db13623..ce745e19aa2 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -187,6 +187,8 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
187 }, 187 },
188}; 188};
189 189
190static struct s3c_hsotg_plat smartq_hsotg_pdata;
191
190static int __init smartq_lcd_setup_gpio(void) 192static int __init smartq_lcd_setup_gpio(void)
191{ 193{
192 int ret; 194 int ret;
@@ -383,6 +385,7 @@ void __init smartq_map_io(void)
383void __init smartq_machine_init(void) 385void __init smartq_machine_init(void)
384{ 386{
385 s3c_i2c0_set_platdata(NULL); 387 s3c_i2c0_set_platdata(NULL);
388 s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
386 s3c_hwmon_set_platdata(&smartq_hwmon_pdata); 389 s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
387 s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); 390 s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
388 s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); 391 s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index ca6fc204f0e..d55bc96d958 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -72,6 +72,7 @@
72#include <plat/keypad.h> 72#include <plat/keypad.h>
73#include <plat/backlight.h> 73#include <plat/backlight.h>
74#include <plat/regs-fb-v4.h> 74#include <plat/regs-fb-v4.h>
75#include <plat/udc-hs.h>
75 76
76#include "common.h" 77#include "common.h"
77 78
@@ -631,6 +632,8 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
631 .pwm_id = 1, 632 .pwm_id = 1,
632}; 633};
633 634
635static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
636
634static void __init smdk6410_map_io(void) 637static void __init smdk6410_map_io(void)
635{ 638{
636 u32 tmp; 639 u32 tmp;
@@ -659,6 +662,7 @@ static void __init smdk6410_machine_init(void)
659 s3c_i2c0_set_platdata(NULL); 662 s3c_i2c0_set_platdata(NULL);
660 s3c_i2c1_set_platdata(NULL); 663 s3c_i2c1_set_platdata(NULL);
661 s3c_fb_set_platdata(&smdk6410_lcd_pdata); 664 s3c_fb_set_platdata(&smdk6410_lcd_pdata);
665 s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
662 666
663 samsung_keypad_set_platdata(&smdk6410_keypad_data); 667 samsung_keypad_set_platdata(&smdk6410_keypad_data);
664 668
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
new file mode 100644
index 00000000000..f6757e02d7d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/platform_device.h>
17#include <mach/map.h>
18#include <mach/regs-sys.h>
19#include <plat/cpu.h>
20#include <plat/regs-usb-hsotg-phy.h>
21#include <plat/usb-phy.h>
22
23static int s3c_usb_otgphy_init(struct platform_device *pdev)
24{
25 struct clk *xusbxti;
26 u32 phyclk;
27
28 writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
29
30 /* set clock frequency for PLL */
31 phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
32
33 xusbxti = clk_get(&pdev->dev, "xusbxti");
34 if (xusbxti && !IS_ERR(xusbxti)) {
35 switch (clk_get_rate(xusbxti)) {
36 case 12 * MHZ:
37 phyclk |= S3C_PHYCLK_CLKSEL_12M;
38 break;
39 case 24 * MHZ:
40 phyclk |= S3C_PHYCLK_CLKSEL_24M;
41 break;
42 default:
43 case 48 * MHZ:
44 /* default reference clock */
45 break;
46 }
47 clk_put(xusbxti);
48 }
49
50 /* TODO: select external clock/oscillator */
51 writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
52
53 /* set to normal OTG PHY */
54 writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
55 mdelay(1);
56
57 /* reset OTG PHY and Link */
58 writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
59 S3C_RSTCON);
60 udelay(20); /* at-least 10uS */
61 writel(0, S3C_RSTCON);
62
63 return 0;
64}
65
66static int s3c_usb_otgphy_exit(struct platform_device *pdev)
67{
68 writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
69 S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
70
71 writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
72
73 return 0;
74}
75
76int s5p_usb_phy_init(struct platform_device *pdev, int type)
77{
78 if (type == S5P_USB_PHY_DEVICE)
79 return s3c_usb_otgphy_init(pdev);
80
81 return -EINVAL;
82}
83
84int s5p_usb_phy_exit(struct platform_device *pdev, int type)
85{
86 if (type == S5P_USB_PHY_DEVICE)
87 return s3c_usb_otgphy_exit(pdev);
88
89 return -EINVAL;
90}
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 2cdc42e838b..82525e3831e 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -65,6 +65,11 @@ config S5PV210_SETUP_SPI
65 help 65 help
66 Common setup code for SPI GPIO configurations. 66 Common setup code for SPI GPIO configurations.
67 67
68config S5PV210_SETUP_USB_PHY
69 bool
70 help
71 Common setup code for USB PHY controller
72
68menu "S5PC110 Machines" 73menu "S5PC110 Machines"
69 74
70config MACH_AQUILA 75config MACH_AQUILA
@@ -107,6 +112,7 @@ config MACH_GONI
107 select S5PV210_SETUP_KEYPAD 112 select S5PV210_SETUP_KEYPAD
108 select S5PV210_SETUP_SDHCI 113 select S5PV210_SETUP_SDHCI
109 select S5PV210_SETUP_FIMC 114 select S5PV210_SETUP_FIMC
115 select S5PV210_SETUP_USB_PHY
110 help 116 help
111 Machine support for Samsung GONI board 117 Machine support for Samsung GONI board
112 S5PC110(MCP) is one of package option of S5PV210 118 S5PC110(MCP) is one of package option of S5PV210
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 76a121dd52b..1c4e41998a1 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -39,3 +39,4 @@ obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o
39obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o 39obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o
40obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 40obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
41obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o 41obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o
42obj-$(CONFIG_S5PV210_SETUP_USB_PHY) += setup-usb-phy.o
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
index 26691d39d0f..cccb1eddaa3 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-sys.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
@@ -13,7 +13,3 @@
13#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) 13#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C)
14#define S5PV210_USB_PHY0_EN (1 << 0) 14#define S5PV210_USB_PHY0_EN (1 << 0)
15#define S5PV210_USB_PHY1_EN (1 << 1) 15#define S5PV210_USB_PHY1_EN (1 << 1)
16
17/* compatibility defines for s3c-hsotg driver */
18#define S3C64XX_OTHERS S5PV210_USB_PHY_CON
19#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c
new file mode 100644
index 00000000000..be39cf4aa91
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-usb-phy.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundationr
8 */
9
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/platform_device.h>
15#include <mach/map.h>
16#include <mach/regs-sys.h>
17#include <plat/cpu.h>
18#include <plat/regs-usb-hsotg-phy.h>
19#include <plat/usb-phy.h>
20
21static int s5pv210_usb_otgphy_init(struct platform_device *pdev)
22{
23 struct clk *xusbxti;
24 u32 phyclk;
25
26 writel(readl(S5PV210_USB_PHY_CON) | S5PV210_USB_PHY0_EN,
27 S5PV210_USB_PHY_CON);
28
29 /* set clock frequency for PLL */
30 phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
31
32 xusbxti = clk_get(&pdev->dev, "xusbxti");
33 if (xusbxti && !IS_ERR(xusbxti)) {
34 switch (clk_get_rate(xusbxti)) {
35 case 12 * MHZ:
36 phyclk |= S3C_PHYCLK_CLKSEL_12M;
37 break;
38 case 24 * MHZ:
39 phyclk |= S3C_PHYCLK_CLKSEL_24M;
40 break;
41 default:
42 case 48 * MHZ:
43 /* default reference clock */
44 break;
45 }
46 clk_put(xusbxti);
47 }
48
49 /* TODO: select external clock/oscillator */
50 writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
51
52 /* set to normal OTG PHY */
53 writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
54 mdelay(1);
55
56 /* reset OTG PHY and Link */
57 writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
58 S3C_RSTCON);
59 udelay(20); /* at-least 10uS */
60 writel(0, S3C_RSTCON);
61
62 return 0;
63}
64
65static int s5pv210_usb_otgphy_exit(struct platform_device *pdev)
66{
67 writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
68 S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
69
70 writel(readl(S5PV210_USB_PHY_CON) & ~S5PV210_USB_PHY0_EN,
71 S5PV210_USB_PHY_CON);
72
73 return 0;
74}
75
76int s5p_usb_phy_init(struct platform_device *pdev, int type)
77{
78 if (type == S5P_USB_PHY_DEVICE)
79 return s5pv210_usb_otgphy_init(pdev);
80
81 return -EINVAL;
82}
83
84int s5p_usb_phy_exit(struct platform_device *pdev, int type)
85{
86 if (type == S5P_USB_PHY_DEVICE)
87 return s5pv210_usb_otgphy_exit(pdev);
88
89 return -EINVAL;
90}
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index bcbb4e8d553..76a79b8a172 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -7,12 +7,15 @@ obj-y += clock.o
7obj-y += timer.o 7obj-y += timer.o
8obj-y += pinmux.o 8obj-y += pinmux.o
9obj-y += fuse.o 9obj-y += fuse.o
10obj-$(CONFIG_CPU_IDLE) += cpuidle.o
11obj-$(CONFIG_CPU_IDLE) += sleep.o
10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o 12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o
11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 13obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o 14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
13obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-tegra20-tables.o 15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-tegra20-tables.o
14obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o 16obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o 17obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
18obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o
16obj-$(CONFIG_SMP) += platsmp.o headsmp.o 19obj-$(CONFIG_SMP) += platsmp.o headsmp.o
17obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 20obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
18obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o 21obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 3c197e2440b..b4124b12a77 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -34,16 +34,38 @@
34#include <asm/hardware/gic.h> 34#include <asm/hardware/gic.h>
35 35
36#include "board.h" 36#include "board.h"
37#include "clock.h"
37 38
38static struct of_device_id tegra_dt_match_table[] __initdata = { 39static struct of_device_id tegra_dt_match_table[] __initdata = {
39 { .compatible = "simple-bus", }, 40 { .compatible = "simple-bus", },
40 {} 41 {}
41}; 42};
42 43
44struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
45 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
46 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL),
47 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL),
48 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL),
49 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL),
50 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL),
51 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
52 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
53 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
54 {}
55};
56
57static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
58 /* name parent rate enabled */
59 { "uartd", "pll_p", 408000000, true },
60 { NULL, NULL, 0, 0},
61};
62
43static void __init tegra30_dt_init(void) 63static void __init tegra30_dt_init(void)
44{ 64{
65 tegra_clk_init_from_table(tegra_dt_clk_init_table);
66
45 of_platform_populate(NULL, tegra_dt_match_table, 67 of_platform_populate(NULL, tegra_dt_match_table,
46 NULL, NULL); 68 tegra30_auxdata_lookup, NULL);
47} 69}
48 70
49static const char *tegra30_dt_board_compat[] = { 71static const char *tegra30_dt_board_compat[] = {
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 8337068a4ab..8dad8d18cb4 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -399,6 +399,28 @@ void tegra_periph_reset_assert(struct clk *c)
399} 399}
400EXPORT_SYMBOL(tegra_periph_reset_assert); 400EXPORT_SYMBOL(tegra_periph_reset_assert);
401 401
402/* Several extended clock configuration bits (e.g., clock routing, clock
403 * phase control) are included in PLL and peripheral clock source
404 * registers. */
405int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
406{
407 int ret = 0;
408 unsigned long flags;
409
410 spin_lock_irqsave(&c->spinlock, flags);
411
412 if (!c->ops || !c->ops->clk_cfg_ex) {
413 ret = -ENOSYS;
414 goto out;
415 }
416 ret = c->ops->clk_cfg_ex(c, p, setting);
417
418out:
419 spin_unlock_irqrestore(&c->spinlock, flags);
420
421 return ret;
422}
423
402#ifdef CONFIG_DEBUG_FS 424#ifdef CONFIG_DEBUG_FS
403 425
404static int __clk_lock_all_spinlocks(void) 426static int __clk_lock_all_spinlocks(void)
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 5c44106616c..bc300657deb 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -24,6 +24,8 @@
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26 26
27#include <mach/clk.h>
28
27#define DIV_BUS (1 << 0) 29#define DIV_BUS (1 << 0)
28#define DIV_U71 (1 << 1) 30#define DIV_U71 (1 << 1)
29#define DIV_U71_FIXED (1 << 2) 31#define DIV_U71_FIXED (1 << 2)
@@ -39,7 +41,16 @@
39#define PERIPH_MANUAL_RESET (1 << 12) 41#define PERIPH_MANUAL_RESET (1 << 12)
40#define PLL_ALT_MISC_REG (1 << 13) 42#define PLL_ALT_MISC_REG (1 << 13)
41#define PLLU (1 << 14) 43#define PLLU (1 << 14)
44#define PLLX (1 << 15)
45#define MUX_PWM (1 << 16)
46#define MUX8 (1 << 17)
47#define DIV_U71_UART (1 << 18)
48#define MUX_CLK_OUT (1 << 19)
49#define PLLM (1 << 20)
50#define DIV_U71_INT (1 << 21)
51#define DIV_U71_IDLE (1 << 22)
42#define ENABLE_ON_INIT (1 << 28) 52#define ENABLE_ON_INIT (1 << 28)
53#define PERIPH_ON_APB (1 << 29)
43 54
44struct clk; 55struct clk;
45 56
@@ -65,6 +76,8 @@ struct clk_ops {
65 int (*set_rate)(struct clk *, unsigned long); 76 int (*set_rate)(struct clk *, unsigned long);
66 long (*round_rate)(struct clk *, unsigned long); 77 long (*round_rate)(struct clk *, unsigned long);
67 void (*reset)(struct clk *, bool); 78 void (*reset)(struct clk *, bool);
79 int (*clk_cfg_ex)(struct clk *,
80 enum tegra_clk_ex_param, u32);
68}; 81};
69 82
70enum clk_state { 83enum clk_state {
@@ -114,6 +127,7 @@ struct clk {
114 unsigned long vco_max; 127 unsigned long vco_max;
115 const struct clk_pll_freq_table *freq_table; 128 const struct clk_pll_freq_table *freq_table;
116 int lock_delay; 129 int lock_delay;
130 unsigned long fixed_rate;
117 } pll; 131 } pll;
118 struct { 132 struct {
119 u32 sel; 133 u32 sel;
@@ -146,6 +160,7 @@ struct tegra_clk_init_table {
146}; 160};
147 161
148void tegra2_init_clocks(void); 162void tegra2_init_clocks(void);
163void tegra30_init_clocks(void);
149void clk_init(struct clk *clk); 164void clk_init(struct clk *clk);
150struct clk *tegra_get_clock_by_name(const char *name); 165struct clk *tegra_get_clock_by_name(const char *name);
151int clk_reparent(struct clk *c, struct clk *parent); 166int clk_reparent(struct clk *c, struct clk *parent);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index fac449e84d8..6c93cd0e520 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -104,6 +104,7 @@ void __init tegra20_init_early(void)
104#ifdef CONFIG_ARCH_TEGRA_3x_SOC 104#ifdef CONFIG_ARCH_TEGRA_3x_SOC
105void __init tegra30_init_early(void) 105void __init tegra30_init_early(void)
106{ 106{
107 tegra30_init_clocks();
107 tegra_init_cache(0x441, 0x551); 108 tegra_init_cache(0x441, 0x551);
108} 109}
109#endif 110#endif
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
new file mode 100644
index 00000000000..d83a8c0296f
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -0,0 +1,107 @@
1/*
2 * arch/arm/mach-tegra/cpuidle.c
3 *
4 * CPU idle driver for Tegra CPUs
5 *
6 * Copyright (c) 2010-2012, NVIDIA Corporation.
7 * Copyright (c) 2011 Google, Inc.
8 * Author: Colin Cross <ccross@android.com>
9 * Gary King <gking@nvidia.com>
10 *
11 * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * more details.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/cpu.h>
27#include <linux/cpuidle.h>
28#include <linux/hrtimer.h>
29
30#include <mach/iomap.h>
31
32extern void tegra_cpu_wfi(void);
33
34static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
35 struct cpuidle_driver *drv, int index);
36
37struct cpuidle_driver tegra_idle_driver = {
38 .name = "tegra_idle",
39 .owner = THIS_MODULE,
40 .state_count = 1,
41 .states = {
42 [0] = {
43 .enter = tegra_idle_enter_lp3,
44 .exit_latency = 10,
45 .target_residency = 10,
46 .power_usage = 600,
47 .flags = CPUIDLE_FLAG_TIME_VALID,
48 .name = "LP3",
49 .desc = "CPU flow-controlled",
50 },
51 },
52};
53
54static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
55
56static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
57 struct cpuidle_driver *drv, int index)
58{
59 ktime_t enter, exit;
60 s64 us;
61
62 local_irq_disable();
63 local_fiq_disable();
64
65 enter = ktime_get();
66
67 tegra_cpu_wfi();
68
69 exit = ktime_sub(ktime_get(), enter);
70 us = ktime_to_us(exit);
71
72 local_fiq_enable();
73 local_irq_enable();
74
75 dev->last_residency = us;
76
77 return index;
78}
79
80static int __init tegra_cpuidle_init(void)
81{
82 int ret;
83 unsigned int cpu;
84 struct cpuidle_device *dev;
85 struct cpuidle_driver *drv = &tegra_idle_driver;
86
87 ret = cpuidle_register_driver(&tegra_idle_driver);
88 if (ret) {
89 pr_err("CPUidle driver registration failed\n");
90 return ret;
91 }
92
93 for_each_possible_cpu(cpu) {
94 dev = &per_cpu(tegra_idle_device, cpu);
95 dev->cpu = cpu;
96
97 dev->state_count = drv->state_count;
98 ret = cpuidle_register_device(dev);
99 if (ret) {
100 pr_err("CPU%u: CPUidle device registration failed\n",
101 cpu);
102 return ret;
103 }
104 }
105 return 0;
106}
107device_initcall(tegra_cpuidle_init);
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
new file mode 100644
index 00000000000..74c6efbe52f
--- /dev/null
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -0,0 +1,37 @@
1/*
2 * arch/arm/mach-tegra/flowctrl.h
3 *
4 * functions and macros to control the flowcontroller
5 *
6 * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef __MACH_TEGRA_FLOWCTRL_H
22#define __MACH_TEGRA_FLOWCTRL_H
23
24#define FLOW_CTRL_HALT_CPU0_EVENTS 0x0
25#define FLOW_CTRL_WAITEVENT (2 << 29)
26#define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29)
27#define FLOW_CTRL_JTAG_RESUME (1 << 28)
28#define FLOW_CTRL_HALT_CPU_IRQ (1 << 10)
29#define FLOW_CTRL_HALT_CPU_FIQ (1 << 8)
30#define FLOW_CTRL_CPU0_CSR 0x8
31#define FLOW_CTRL_CSR_INTR_FLAG (1 << 15)
32#define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14)
33#define FLOW_CTRL_CSR_ENABLE (1 << 0)
34#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14
35#define FLOW_CTRL_CPU1_CSR 0x18
36
37#endif
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index fc3ecb66de0..d97e403303a 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -22,10 +22,20 @@
22 22
23struct clk; 23struct clk;
24 24
25enum tegra_clk_ex_param {
26 TEGRA_CLK_VI_INP_SEL,
27 TEGRA_CLK_DTV_INVERT,
28 TEGRA_CLK_NAND_PAD_DIV2_ENB,
29 TEGRA_CLK_PLLD_CSI_OUT_ENB,
30 TEGRA_CLK_PLLD_DSI_OUT_ENB,
31 TEGRA_CLK_PLLD_MIPI_MUX_SEL,
32};
33
25void tegra_periph_reset_deassert(struct clk *c); 34void tegra_periph_reset_deassert(struct clk *c);
26void tegra_periph_reset_assert(struct clk *c); 35void tegra_periph_reset_assert(struct clk *c);
27 36
28unsigned long clk_get_rate_all_locked(struct clk *c); 37unsigned long clk_get_rate_all_locked(struct clk *c);
29void tegra2_sdmmc_tap_delay(struct clk *c, int delay); 38void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
39int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
30 40
31#endif 41#endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 19dec3ac085..67644c905d8 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -74,6 +74,9 @@
74#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 74#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
75#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 75#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
76 76
77#define TEGRA_QUINARY_ICTLR_BASE 0x60004400
78#define TEGRA_QUINARY_ICTLR_SIZE SZ_64
79
77#define TEGRA_TMR1_BASE 0x60005000 80#define TEGRA_TMR1_BASE 0x60005000
78#define TEGRA_TMR1_SIZE SZ_8 81#define TEGRA_TMR1_SIZE SZ_8
79 82
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index a2146cd6867..aad1a2c1d71 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -165,11 +165,12 @@
165#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30) 165#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
166#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31) 166#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
167 167
168#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE) 168/* Tegra30 has 5 banks of 32 IRQs */
169 169#define INT_MAIN_NR (32 * 5)
170#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR) 170#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR)
171 171
172#define INT_GPIO_NR (28 * 8) 172/* Tegra30 has 8 banks of 32 GPIOs */
173#define INT_GPIO_NR (32 * 8)
173 174
174#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) 175#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
175 176
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 4e1afcd54fa..2f5bd2db8e1 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -44,14 +44,16 @@
44#define ICTLR_COP_IER_CLR 0x38 44#define ICTLR_COP_IER_CLR 0x38
45#define ICTLR_COP_IEP_CLASS 0x3c 45#define ICTLR_COP_IEP_CLASS 0x3c
46 46
47#define NUM_ICTLRS 4
48#define FIRST_LEGACY_IRQ 32 47#define FIRST_LEGACY_IRQ 32
49 48
49static int num_ictlrs;
50
50static void __iomem *ictlr_reg_base[] = { 51static void __iomem *ictlr_reg_base[] = {
51 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), 52 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
52 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), 53 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
53 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), 54 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
54 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), 55 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
56 IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
55}; 57};
56 58
57static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) 59static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
@@ -60,7 +62,7 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
60 u32 mask; 62 u32 mask;
61 63
62 BUG_ON(irq < FIRST_LEGACY_IRQ || 64 BUG_ON(irq < FIRST_LEGACY_IRQ ||
63 irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32); 65 irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
64 66
65 base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; 67 base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
66 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); 68 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
@@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d)
113void __init tegra_init_irq(void) 115void __init tegra_init_irq(void)
114{ 116{
115 int i; 117 int i;
118 void __iomem *distbase;
119
120 distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
121 num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
122
123 if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
124 WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
125 num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
126 num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
127 }
116 128
117 for (i = 0; i < NUM_ICTLRS; i++) { 129 for (i = 0; i < num_ictlrs; i++) {
118 void __iomem *ictlr = ictlr_reg_base[i]; 130 void __iomem *ictlr = ictlr_reg_base[i];
119 writel(~0, ictlr + ICTLR_CPU_IER_CLR); 131 writel(~0, ictlr + ICTLR_CPU_IER_CLR);
120 writel(0, ictlr + ICTLR_CPU_IEP_CLASS); 132 writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
@@ -131,6 +143,6 @@ void __init tegra_init_irq(void)
131 * initialized elsewhere under DT. 143 * initialized elsewhere under DT.
132 */ 144 */
133 if (!of_have_populated_dt()) 145 if (!of_have_populated_dt())
134 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 146 gic_init(0, 29, distbase,
135 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); 147 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
136} 148}
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
new file mode 100644
index 00000000000..8f9fde161c3
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep.S
@@ -0,0 +1,91 @@
1/*
2 * arch/arm/mach-tegra/sleep.S
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 * Copyright (c) 2011, Google, Inc.
6 *
7 * Author: Colin Cross <ccross@android.com>
8 * Gary King <gking@nvidia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25#include <linux/linkage.h>
26#include <mach/io.h>
27#include <mach/iomap.h>
28
29#include "flowctrl.h"
30
31#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
32 + IO_PPSB_VIRT)
33
34/* returns the offset of the flow controller halt register for a cpu */
35.macro cpu_to_halt_reg rd, rcpu
36 cmp \rcpu, #0
37 subne \rd, \rcpu, #1
38 movne \rd, \rd, lsl #3
39 addne \rd, \rd, #0x14
40 moveq \rd, #0
41.endm
42
43/* returns the offset of the flow controller csr register for a cpu */
44.macro cpu_to_csr_reg rd, rcpu
45 cmp \rcpu, #0
46 subne \rd, \rcpu, #1
47 movne \rd, \rd, lsl #3
48 addne \rd, \rd, #0x18
49 moveq \rd, #8
50.endm
51
52/* returns the ID of the current processor */
53.macro cpu_id, rd
54 mrc p15, 0, \rd, c0, c0, 5
55 and \rd, \rd, #0xF
56.endm
57
58/* loads a 32-bit value into a register without a data access */
59.macro mov32, reg, val
60 movw \reg, #:lower16:\val
61 movt \reg, #:upper16:\val
62.endm
63
64/*
65 * tegra_cpu_wfi
66 *
67 * puts current CPU in clock-gated wfi using the flow controller
68 *
69 * corrupts r0-r3
70 * must be called with MMU on
71 */
72
73ENTRY(tegra_cpu_wfi)
74 cpu_id r0
75 cpu_to_halt_reg r1, r0
76 cpu_to_csr_reg r2, r0
77 mov32 r0, TEGRA_FLOW_CTRL_VIRT
78 mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
79 str r3, [r0, r2] @ clear event & interrupt status
80 mov r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME
81 str r3, [r0, r1] @ put flow controller in wait irq mode
82 dsb
83 wfi
84 mov r3, #0
85 str r3, [r0, r1] @ clear flow controller halt status
86 mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
87 str r3, [r0, r2] @ clear event & interrupt status
88 dsb
89 mov pc, lr
90ENDPROC(tegra_cpu_wfi)
91
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ff9e6b6c046..1976e934cdd 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -1143,15 +1143,35 @@ static void tegra2_emc_clk_init(struct clk *c)
1143 1143
1144static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate) 1144static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1145{ 1145{
1146 long new_rate = rate; 1146 long emc_rate;
1147 long clk_rate;
1147 1148
1148 new_rate = tegra_emc_round_rate(new_rate); 1149 /*
1149 if (new_rate < 0) 1150 * The slowest entry in the EMC clock table that is at least as
1151 * fast as rate.
1152 */
1153 emc_rate = tegra_emc_round_rate(rate);
1154 if (emc_rate < 0)
1150 return c->max_rate; 1155 return c->max_rate;
1151 1156
1152 BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate)); 1157 /*
1158 * The fastest rate the PLL will generate that is at most the
1159 * requested rate.
1160 */
1161 clk_rate = tegra2_periph_clk_round_rate(c, emc_rate);
1162
1163 /*
1164 * If this fails, and emc_rate > clk_rate, it's because the maximum
1165 * rate in the EMC tables is larger than the maximum rate of the EMC
1166 * clock. The EMC clock's max rate is the rate it was running when the
1167 * kernel booted. Such a mismatch is probably due to using the wrong
1168 * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25.
1169 */
1170 WARN_ONCE(emc_rate != clk_rate,
1171 "emc_rate %ld != clk_rate %ld",
1172 emc_rate, clk_rate);
1153 1173
1154 return new_rate; 1174 return emc_rate;
1155} 1175}
1156 1176
1157static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate) 1177static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
new file mode 100644
index 00000000000..6d08b53f92d
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra30_clocks.c
@@ -0,0 +1,3099 @@
1/*
2 * arch/arm/mach-tegra/tegra30_clocks.c
3 *
4 * Copyright (c) 2010-2011 NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/list.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/clk.h>
29#include <linux/cpufreq.h>
30#include <linux/syscore_ops.h>
31
32#include <asm/clkdev.h>
33
34#include <mach/iomap.h>
35
36#include "clock.h"
37#include "fuse.h"
38
39#define USE_PLL_LOCK_BITS 0
40
41#define RST_DEVICES_L 0x004
42#define RST_DEVICES_H 0x008
43#define RST_DEVICES_U 0x00C
44#define RST_DEVICES_V 0x358
45#define RST_DEVICES_W 0x35C
46#define RST_DEVICES_SET_L 0x300
47#define RST_DEVICES_CLR_L 0x304
48#define RST_DEVICES_SET_V 0x430
49#define RST_DEVICES_CLR_V 0x434
50#define RST_DEVICES_NUM 5
51
52#define CLK_OUT_ENB_L 0x010
53#define CLK_OUT_ENB_H 0x014
54#define CLK_OUT_ENB_U 0x018
55#define CLK_OUT_ENB_V 0x360
56#define CLK_OUT_ENB_W 0x364
57#define CLK_OUT_ENB_SET_L 0x320
58#define CLK_OUT_ENB_CLR_L 0x324
59#define CLK_OUT_ENB_SET_V 0x440
60#define CLK_OUT_ENB_CLR_V 0x444
61#define CLK_OUT_ENB_NUM 5
62
63#define RST_DEVICES_V_SWR_CPULP_RST_DIS (0x1 << 1)
64#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1)
65
66#define PERIPH_CLK_TO_BIT(c) (1 << (c->u.periph.clk_num % 32))
67#define PERIPH_CLK_TO_RST_REG(c) \
68 periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4)
69#define PERIPH_CLK_TO_RST_SET_REG(c) \
70 periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8)
71#define PERIPH_CLK_TO_RST_CLR_REG(c) \
72 periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8)
73
74#define PERIPH_CLK_TO_ENB_REG(c) \
75 periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4)
76#define PERIPH_CLK_TO_ENB_SET_REG(c) \
77 periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8)
78#define PERIPH_CLK_TO_ENB_CLR_REG(c) \
79 periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8)
80
81#define CLK_MASK_ARM 0x44
82#define MISC_CLK_ENB 0x48
83
84#define OSC_CTRL 0x50
85#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
86#define OSC_CTRL_OSC_FREQ_13MHZ (0x0<<28)
87#define OSC_CTRL_OSC_FREQ_19_2MHZ (0x4<<28)
88#define OSC_CTRL_OSC_FREQ_12MHZ (0x8<<28)
89#define OSC_CTRL_OSC_FREQ_26MHZ (0xC<<28)
90#define OSC_CTRL_OSC_FREQ_16_8MHZ (0x1<<28)
91#define OSC_CTRL_OSC_FREQ_38_4MHZ (0x5<<28)
92#define OSC_CTRL_OSC_FREQ_48MHZ (0x9<<28)
93#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
94
95#define OSC_CTRL_PLL_REF_DIV_MASK (3<<26)
96#define OSC_CTRL_PLL_REF_DIV_1 (0<<26)
97#define OSC_CTRL_PLL_REF_DIV_2 (1<<26)
98#define OSC_CTRL_PLL_REF_DIV_4 (2<<26)
99
100#define OSC_FREQ_DET 0x58
101#define OSC_FREQ_DET_TRIG (1<<31)
102
103#define OSC_FREQ_DET_STATUS 0x5C
104#define OSC_FREQ_DET_BUSY (1<<31)
105#define OSC_FREQ_DET_CNT_MASK 0xFFFF
106
107#define PERIPH_CLK_SOURCE_I2S1 0x100
108#define PERIPH_CLK_SOURCE_EMC 0x19c
109#define PERIPH_CLK_SOURCE_OSC 0x1fc
110#define PERIPH_CLK_SOURCE_NUM1 \
111 ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
112
113#define PERIPH_CLK_SOURCE_G3D2 0x3b0
114#define PERIPH_CLK_SOURCE_SE 0x42c
115#define PERIPH_CLK_SOURCE_NUM2 \
116 ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1)
117
118#define AUDIO_DLY_CLK 0x49c
119#define AUDIO_SYNC_CLK_SPDIF 0x4b4
120#define PERIPH_CLK_SOURCE_NUM3 \
121 ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1)
122
123#define PERIPH_CLK_SOURCE_NUM (PERIPH_CLK_SOURCE_NUM1 + \
124 PERIPH_CLK_SOURCE_NUM2 + \
125 PERIPH_CLK_SOURCE_NUM3)
126
127#define CPU_SOFTRST_CTRL 0x380
128
129#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
130#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
131#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
132#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT 8
133#define PERIPH_CLK_SOURCE_DIVIDLE_VAL 50
134#define PERIPH_CLK_UART_DIV_ENB (1<<24)
135#define PERIPH_CLK_VI_SEL_EX_SHIFT 24
136#define PERIPH_CLK_VI_SEL_EX_MASK (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT)
137#define PERIPH_CLK_NAND_DIV_EX_ENB (1<<8)
138#define PERIPH_CLK_DTV_POLARITY_INV (1<<25)
139
140#define AUDIO_SYNC_SOURCE_MASK 0x0F
141#define AUDIO_SYNC_DISABLE_BIT 0x10
142#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4)
143
144#define PLL_BASE 0x0
145#define PLL_BASE_BYPASS (1<<31)
146#define PLL_BASE_ENABLE (1<<30)
147#define PLL_BASE_REF_ENABLE (1<<29)
148#define PLL_BASE_OVERRIDE (1<<28)
149#define PLL_BASE_LOCK (1<<27)
150#define PLL_BASE_DIVP_MASK (0x7<<20)
151#define PLL_BASE_DIVP_SHIFT 20
152#define PLL_BASE_DIVN_MASK (0x3FF<<8)
153#define PLL_BASE_DIVN_SHIFT 8
154#define PLL_BASE_DIVM_MASK (0x1F)
155#define PLL_BASE_DIVM_SHIFT 0
156
157#define PLL_OUT_RATIO_MASK (0xFF<<8)
158#define PLL_OUT_RATIO_SHIFT 8
159#define PLL_OUT_OVERRIDE (1<<2)
160#define PLL_OUT_CLKEN (1<<1)
161#define PLL_OUT_RESET_DISABLE (1<<0)
162
163#define PLL_MISC(c) \
164 (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
165#define PLL_MISC_LOCK_ENABLE(c) \
166 (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18))
167
168#define PLL_MISC_DCCON_SHIFT 20
169#define PLL_MISC_CPCON_SHIFT 8
170#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
171#define PLL_MISC_LFCON_SHIFT 4
172#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
173#define PLL_MISC_VCOCON_SHIFT 0
174#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
175#define PLLD_MISC_CLKENABLE (1<<30)
176
177#define PLLU_BASE_POST_DIV (1<<20)
178
179#define PLLD_BASE_DSIB_MUX_SHIFT 25
180#define PLLD_BASE_DSIB_MUX_MASK (1<<PLLD_BASE_DSIB_MUX_SHIFT)
181#define PLLD_BASE_CSI_CLKENABLE (1<<26)
182#define PLLD_MISC_DSI_CLKENABLE (1<<30)
183#define PLLD_MISC_DIV_RST (1<<23)
184#define PLLD_MISC_DCCON_SHIFT 12
185
186#define PLLDU_LFCON_SET_DIVN 600
187
188/* FIXME: OUT_OF_TABLE_CPCON per pll */
189#define OUT_OF_TABLE_CPCON 0x8
190
191#define SUPER_CLK_MUX 0x00
192#define SUPER_STATE_SHIFT 28
193#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
194#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
195#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
196#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
197#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
198#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
199#define SUPER_LP_DIV2_BYPASS (0x1 << 16)
200#define SUPER_SOURCE_MASK 0xF
201#define SUPER_FIQ_SOURCE_SHIFT 12
202#define SUPER_IRQ_SOURCE_SHIFT 8
203#define SUPER_RUN_SOURCE_SHIFT 4
204#define SUPER_IDLE_SOURCE_SHIFT 0
205
206#define SUPER_CLK_DIVIDER 0x04
207#define SUPER_CLOCK_DIV_U71_SHIFT 16
208#define SUPER_CLOCK_DIV_U71_MASK (0xff << SUPER_CLOCK_DIV_U71_SHIFT)
209/* guarantees safe cpu backup */
210#define SUPER_CLOCK_DIV_U71_MIN 0x2
211
212#define BUS_CLK_DISABLE (1<<3)
213#define BUS_CLK_DIV_MASK 0x3
214
215#define PMC_CTRL 0x0
216 #define PMC_CTRL_BLINK_ENB (1 << 7)
217
218#define PMC_DPD_PADS_ORIDE 0x1c
219 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
220
221#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
222#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
223#define PMC_BLINK_TIMER_ENB (1 << 15)
224#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
225#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
226
227#define PMC_PLLP_WB0_OVERRIDE 0xf8
228#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE (1 << 12)
229
230#define UTMIP_PLL_CFG2 0x488
231#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6)
232#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
233#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN (1 << 0)
234#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN (1 << 2)
235#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN (1 << 4)
236
237#define UTMIP_PLL_CFG1 0x484
238#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
239#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
240#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN (1 << 14)
241#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN (1 << 12)
242#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN (1 << 16)
243
244#define PLLE_BASE_CML_ENABLE (1<<31)
245#define PLLE_BASE_ENABLE (1<<30)
246#define PLLE_BASE_DIVCML_SHIFT 24
247#define PLLE_BASE_DIVCML_MASK (0xf<<PLLE_BASE_DIVCML_SHIFT)
248#define PLLE_BASE_DIVP_SHIFT 16
249#define PLLE_BASE_DIVP_MASK (0x3f<<PLLE_BASE_DIVP_SHIFT)
250#define PLLE_BASE_DIVN_SHIFT 8
251#define PLLE_BASE_DIVN_MASK (0xFF<<PLLE_BASE_DIVN_SHIFT)
252#define PLLE_BASE_DIVM_SHIFT 0
253#define PLLE_BASE_DIVM_MASK (0xFF<<PLLE_BASE_DIVM_SHIFT)
254#define PLLE_BASE_DIV_MASK \
255 (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \
256 PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK)
257#define PLLE_BASE_DIV(m, n, p, cml) \
258 (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \
259 ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT))
260
261#define PLLE_MISC_SETUP_BASE_SHIFT 16
262#define PLLE_MISC_SETUP_BASE_MASK (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT)
263#define PLLE_MISC_READY (1<<15)
264#define PLLE_MISC_LOCK (1<<11)
265#define PLLE_MISC_LOCK_ENABLE (1<<9)
266#define PLLE_MISC_SETUP_EX_SHIFT 2
267#define PLLE_MISC_SETUP_EX_MASK (0x3<<PLLE_MISC_SETUP_EX_SHIFT)
268#define PLLE_MISC_SETUP_MASK \
269 (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK)
270#define PLLE_MISC_SETUP_VALUE \
271 ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT))
272
273#define PLLE_SS_CTRL 0x68
274#define PLLE_SS_INCINTRV_SHIFT 24
275#define PLLE_SS_INCINTRV_MASK (0x3f<<PLLE_SS_INCINTRV_SHIFT)
276#define PLLE_SS_INC_SHIFT 16
277#define PLLE_SS_INC_MASK (0xff<<PLLE_SS_INC_SHIFT)
278#define PLLE_SS_MAX_SHIFT 0
279#define PLLE_SS_MAX_MASK (0x1ff<<PLLE_SS_MAX_SHIFT)
280#define PLLE_SS_COEFFICIENTS_MASK \
281 (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
282#define PLLE_SS_COEFFICIENTS_12MHZ \
283 ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
284 (0x24<<PLLE_SS_MAX_SHIFT))
285#define PLLE_SS_DISABLE ((1<<12) | (1<<11) | (1<<10))
286
287#define PLLE_AUX 0x48c
288#define PLLE_AUX_PLLP_SEL (1<<2)
289#define PLLE_AUX_CML_SATA_ENABLE (1<<1)
290#define PLLE_AUX_CML_PCIE_ENABLE (1<<0)
291
292#define PMC_SATA_PWRGT 0x1ac
293#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5)
294#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4)
295
296#define ROUND_DIVIDER_UP 0
297#define ROUND_DIVIDER_DOWN 1
298
299/* FIXME: recommended safety delay after lock is detected */
300#define PLL_POST_LOCK_DELAY 100
301
302/**
303* Structure defining the fields for USB UTMI clocks Parameters.
304*/
305struct utmi_clk_param {
306 /* Oscillator Frequency in KHz */
307 u32 osc_frequency;
308 /* UTMIP PLL Enable Delay Count */
309 u8 enable_delay_count;
310 /* UTMIP PLL Stable count */
311 u8 stable_count;
312 /* UTMIP PLL Active delay count */
313 u8 active_delay_count;
314 /* UTMIP PLL Xtal frequency count */
315 u8 xtal_freq_count;
316};
317
318static const struct utmi_clk_param utmi_parameters[] = {
319 {
320 .osc_frequency = 13000000,
321 .enable_delay_count = 0x02,
322 .stable_count = 0x33,
323 .active_delay_count = 0x05,
324 .xtal_freq_count = 0x7F
325 },
326 {
327 .osc_frequency = 19200000,
328 .enable_delay_count = 0x03,
329 .stable_count = 0x4B,
330 .active_delay_count = 0x06,
331 .xtal_freq_count = 0xBB},
332 {
333 .osc_frequency = 12000000,
334 .enable_delay_count = 0x02,
335 .stable_count = 0x2F,
336 .active_delay_count = 0x04,
337 .xtal_freq_count = 0x76
338 },
339 {
340 .osc_frequency = 26000000,
341 .enable_delay_count = 0x04,
342 .stable_count = 0x66,
343 .active_delay_count = 0x09,
344 .xtal_freq_count = 0xFE
345 },
346 {
347 .osc_frequency = 16800000,
348 .enable_delay_count = 0x03,
349 .stable_count = 0x41,
350 .active_delay_count = 0x0A,
351 .xtal_freq_count = 0xA4
352 },
353};
354
355static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
356static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
357static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
358
359#define MISC_GP_HIDREV 0x804
360
361/*
362 * Some peripheral clocks share an enable bit, so refcount the enable bits
363 * in registers CLK_ENABLE_L, ... CLK_ENABLE_W
364 */
365static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
366
367#define clk_writel(value, reg) \
368 __raw_writel(value, (u32)reg_clk_base + (reg))
369#define clk_readl(reg) \
370 __raw_readl((u32)reg_clk_base + (reg))
371#define pmc_writel(value, reg) \
372 __raw_writel(value, (u32)reg_pmc_base + (reg))
373#define pmc_readl(reg) \
374 __raw_readl((u32)reg_pmc_base + (reg))
375#define chipid_readl() \
376 __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
377
378#define clk_writel_delay(value, reg) \
379 do { \
380 __raw_writel((value), (u32)reg_clk_base + (reg)); \
381 udelay(2); \
382 } while (0)
383
384
385static inline int clk_set_div(struct clk *c, u32 n)
386{
387 return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
388}
389
390static inline u32 periph_clk_to_reg(
391 struct clk *c, u32 reg_L, u32 reg_V, int offs)
392{
393 u32 reg = c->u.periph.clk_num / 32;
394 BUG_ON(reg >= RST_DEVICES_NUM);
395 if (reg < 3)
396 reg = reg_L + (reg * offs);
397 else
398 reg = reg_V + ((reg - 3) * offs);
399 return reg;
400}
401
402static unsigned long clk_measure_input_freq(void)
403{
404 u32 clock_autodetect;
405 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
406 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
407 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
408 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
409 return 12000000;
410 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
411 return 13000000;
412 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
413 return 19200000;
414 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
415 return 26000000;
416 } else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) {
417 return 16800000;
418 } else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) {
419 return 38400000;
420 } else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) {
421 return 48000000;
422 } else {
423 pr_err("%s: Unexpected clock autodetect value %d", __func__,
424 clock_autodetect);
425 BUG();
426 return 0;
427 }
428}
429
430static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate,
431 u32 flags, u32 round_mode)
432{
433 s64 divider_u71 = parent_rate;
434 if (!rate)
435 return -EINVAL;
436
437 if (!(flags & DIV_U71_INT))
438 divider_u71 *= 2;
439 if (round_mode == ROUND_DIVIDER_UP)
440 divider_u71 += rate - 1;
441 do_div(divider_u71, rate);
442 if (flags & DIV_U71_INT)
443 divider_u71 *= 2;
444
445 if (divider_u71 - 2 < 0)
446 return 0;
447
448 if (divider_u71 - 2 > 255)
449 return -EINVAL;
450
451 return divider_u71 - 2;
452}
453
454static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
455{
456 s64 divider_u16;
457
458 divider_u16 = parent_rate;
459 if (!rate)
460 return -EINVAL;
461 divider_u16 += rate - 1;
462 do_div(divider_u16, rate);
463
464 if (divider_u16 - 1 < 0)
465 return 0;
466
467 if (divider_u16 - 1 > 0xFFFF)
468 return -EINVAL;
469
470 return divider_u16 - 1;
471}
472
473/* clk_m functions */
474static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c)
475{
476 u32 osc_ctrl = clk_readl(OSC_CTRL);
477 u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
478 u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
479
480 c->rate = clk_measure_input_freq();
481 switch (c->rate) {
482 case 12000000:
483 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
484 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
485 break;
486 case 13000000:
487 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
488 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
489 break;
490 case 19200000:
491 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
492 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
493 break;
494 case 26000000:
495 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
496 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
497 break;
498 case 16800000:
499 auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ;
500 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
501 break;
502 case 38400000:
503 auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ;
504 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
505 break;
506 case 48000000:
507 auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ;
508 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
509 break;
510 default:
511 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
512 BUG();
513 }
514 clk_writel(auto_clock_control, OSC_CTRL);
515 return c->rate;
516}
517
518static void tegra30_clk_m_init(struct clk *c)
519{
520 pr_debug("%s on clock %s\n", __func__, c->name);
521 tegra30_clk_m_autodetect_rate(c);
522}
523
524static int tegra30_clk_m_enable(struct clk *c)
525{
526 pr_debug("%s on clock %s\n", __func__, c->name);
527 return 0;
528}
529
530static void tegra30_clk_m_disable(struct clk *c)
531{
532 pr_debug("%s on clock %s\n", __func__, c->name);
533 WARN(1, "Attempting to disable main SoC clock\n");
534}
535
536static struct clk_ops tegra_clk_m_ops = {
537 .init = tegra30_clk_m_init,
538 .enable = tegra30_clk_m_enable,
539 .disable = tegra30_clk_m_disable,
540};
541
542static struct clk_ops tegra_clk_m_div_ops = {
543 .enable = tegra30_clk_m_enable,
544};
545
546/* PLL reference divider functions */
547static void tegra30_pll_ref_init(struct clk *c)
548{
549 u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
550 pr_debug("%s on clock %s\n", __func__, c->name);
551
552 switch (pll_ref_div) {
553 case OSC_CTRL_PLL_REF_DIV_1:
554 c->div = 1;
555 break;
556 case OSC_CTRL_PLL_REF_DIV_2:
557 c->div = 2;
558 break;
559 case OSC_CTRL_PLL_REF_DIV_4:
560 c->div = 4;
561 break;
562 default:
563 pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div);
564 BUG();
565 }
566 c->mul = 1;
567 c->state = ON;
568}
569
570static struct clk_ops tegra_pll_ref_ops = {
571 .init = tegra30_pll_ref_init,
572 .enable = tegra30_clk_m_enable,
573 .disable = tegra30_clk_m_disable,
574};
575
576/* super clock functions */
577/* "super clocks" on tegra30 have two-stage muxes, fractional 7.1 divider and
578 * clock skipping super divider. We will ignore the clock skipping divider,
579 * since we can't lower the voltage when using the clock skip, but we can if
580 * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock
581 * only when its parent is a fixed rate PLL, since we can't change PLL rate
582 * in this case.
583 */
584static void tegra30_super_clk_init(struct clk *c)
585{
586 u32 val;
587 int source;
588 int shift;
589 const struct clk_mux_sel *sel;
590 val = clk_readl(c->reg + SUPER_CLK_MUX);
591 c->state = ON;
592 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
593 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
594 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
595 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
596 source = (val >> shift) & SUPER_SOURCE_MASK;
597 if (c->flags & DIV_2)
598 source |= val & SUPER_LP_DIV2_BYPASS;
599 for (sel = c->inputs; sel->input != NULL; sel++) {
600 if (sel->value == source)
601 break;
602 }
603 BUG_ON(sel->input == NULL);
604 c->parent = sel->input;
605
606 if (c->flags & DIV_U71) {
607 /* Init safe 7.1 divider value (does not affect PLLX path) */
608 clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT,
609 c->reg + SUPER_CLK_DIVIDER);
610 c->mul = 2;
611 c->div = 2;
612 if (!(c->parent->flags & PLLX))
613 c->div += SUPER_CLOCK_DIV_U71_MIN;
614 } else
615 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
616}
617
618static int tegra30_super_clk_enable(struct clk *c)
619{
620 return 0;
621}
622
623static void tegra30_super_clk_disable(struct clk *c)
624{
625 /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and
626 geared up g-mode super clock - mode switch may request to disable
627 either of them; accept request with no affect on h/w */
628}
629
630static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p)
631{
632 u32 val;
633 const struct clk_mux_sel *sel;
634 int shift;
635
636 val = clk_readl(c->reg + SUPER_CLK_MUX);
637 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
638 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
639 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
640 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
641 for (sel = c->inputs; sel->input != NULL; sel++) {
642 if (sel->input == p) {
643 /* For LP mode super-clock switch between PLLX direct
644 and divided-by-2 outputs is allowed only when other
645 than PLLX clock source is current parent */
646 if ((c->flags & DIV_2) && (p->flags & PLLX) &&
647 ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) {
648 if (c->parent->flags & PLLX)
649 return -EINVAL;
650 val ^= SUPER_LP_DIV2_BYPASS;
651 clk_writel_delay(val, c->reg);
652 }
653 val &= ~(SUPER_SOURCE_MASK << shift);
654 val |= (sel->value & SUPER_SOURCE_MASK) << shift;
655
656 /* 7.1 divider for CPU super-clock does not affect
657 PLLX path */
658 if (c->flags & DIV_U71) {
659 u32 div = 0;
660 if (!(p->flags & PLLX)) {
661 div = clk_readl(c->reg +
662 SUPER_CLK_DIVIDER);
663 div &= SUPER_CLOCK_DIV_U71_MASK;
664 div >>= SUPER_CLOCK_DIV_U71_SHIFT;
665 }
666 c->div = div + 2;
667 c->mul = 2;
668 }
669
670 if (c->refcnt)
671 clk_enable(p);
672
673 clk_writel_delay(val, c->reg);
674
675 if (c->refcnt && c->parent)
676 clk_disable(c->parent);
677
678 clk_reparent(c, p);
679 return 0;
680 }
681 }
682 return -EINVAL;
683}
684
685/*
686 * Do not use super clocks "skippers", since dividing using a clock skipper
687 * does not allow the voltage to be scaled down. Instead adjust the rate of
688 * the parent clock. This requires that the parent of a super clock have no
689 * other children, otherwise the rate will change underneath the other
690 * children. Special case: if fixed rate PLL is CPU super clock parent the
691 * rate of this PLL can't be changed, and it has many other children. In
692 * this case use 7.1 fractional divider to adjust the super clock rate.
693 */
694static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate)
695{
696 if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) {
697 int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate,
698 rate, c->flags, ROUND_DIVIDER_DOWN);
699 div = max(div, SUPER_CLOCK_DIV_U71_MIN);
700
701 clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT,
702 c->reg + SUPER_CLK_DIVIDER);
703 c->div = div + 2;
704 c->mul = 2;
705 return 0;
706 }
707 return clk_set_rate(c->parent, rate);
708}
709
710static struct clk_ops tegra_super_ops = {
711 .init = tegra30_super_clk_init,
712 .enable = tegra30_super_clk_enable,
713 .disable = tegra30_super_clk_disable,
714 .set_parent = tegra30_super_clk_set_parent,
715 .set_rate = tegra30_super_clk_set_rate,
716};
717
718static int tegra30_twd_clk_set_rate(struct clk *c, unsigned long rate)
719{
720 /* The input value 'rate' is the clock rate of the CPU complex. */
721 c->rate = (rate * c->mul) / c->div;
722 return 0;
723}
724
725static struct clk_ops tegra30_twd_ops = {
726 .set_rate = tegra30_twd_clk_set_rate,
727};
728
729/* Blink output functions */
730
731static void tegra30_blink_clk_init(struct clk *c)
732{
733 u32 val;
734
735 val = pmc_readl(PMC_CTRL);
736 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
737 c->mul = 1;
738 val = pmc_readl(c->reg);
739
740 if (val & PMC_BLINK_TIMER_ENB) {
741 unsigned int on_off;
742
743 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
744 PMC_BLINK_TIMER_DATA_ON_MASK;
745 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
746 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
747 on_off += val;
748 /* each tick in the blink timer is 4 32KHz clocks */
749 c->div = on_off * 4;
750 } else {
751 c->div = 1;
752 }
753}
754
755static int tegra30_blink_clk_enable(struct clk *c)
756{
757 u32 val;
758
759 val = pmc_readl(PMC_DPD_PADS_ORIDE);
760 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
761
762 val = pmc_readl(PMC_CTRL);
763 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
764
765 return 0;
766}
767
768static void tegra30_blink_clk_disable(struct clk *c)
769{
770 u32 val;
771
772 val = pmc_readl(PMC_CTRL);
773 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
774
775 val = pmc_readl(PMC_DPD_PADS_ORIDE);
776 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
777}
778
779static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate)
780{
781 unsigned long parent_rate = clk_get_rate(c->parent);
782 if (rate >= parent_rate) {
783 c->div = 1;
784 pmc_writel(0, c->reg);
785 } else {
786 unsigned int on_off;
787 u32 val;
788
789 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
790 c->div = on_off * 8;
791
792 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
793 PMC_BLINK_TIMER_DATA_ON_SHIFT;
794 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
795 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
796 val |= on_off;
797 val |= PMC_BLINK_TIMER_ENB;
798 pmc_writel(val, c->reg);
799 }
800
801 return 0;
802}
803
804static struct clk_ops tegra_blink_clk_ops = {
805 .init = &tegra30_blink_clk_init,
806 .enable = &tegra30_blink_clk_enable,
807 .disable = &tegra30_blink_clk_disable,
808 .set_rate = &tegra30_blink_clk_set_rate,
809};
810
811/* PLL Functions */
812static int tegra30_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg,
813 u32 lock_bit)
814{
815#if USE_PLL_LOCK_BITS
816 int i;
817 for (i = 0; i < c->u.pll.lock_delay; i++) {
818 if (clk_readl(lock_reg) & lock_bit) {
819 udelay(PLL_POST_LOCK_DELAY);
820 return 0;
821 }
822 udelay(2); /* timeout = 2 * lock time */
823 }
824 pr_err("Timed out waiting for lock bit on pll %s", c->name);
825 return -1;
826#endif
827 udelay(c->u.pll.lock_delay);
828
829 return 0;
830}
831
832
833static void tegra30_utmi_param_configure(struct clk *c)
834{
835 u32 reg;
836 int i;
837 unsigned long main_rate =
838 clk_get_rate(c->parent->parent);
839
840 for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
841 if (main_rate == utmi_parameters[i].osc_frequency)
842 break;
843 }
844
845 if (i >= ARRAY_SIZE(utmi_parameters)) {
846 pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate);
847 return;
848 }
849
850 reg = clk_readl(UTMIP_PLL_CFG2);
851
852 /* Program UTMIP PLL stable and active counts */
853 /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
854 reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
855 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
856 utmi_parameters[i].stable_count);
857
858 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
859
860 reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
861 utmi_parameters[i].active_delay_count);
862
863 /* Remove power downs from UTMIP PLL control bits */
864 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
865 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
866 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
867
868 clk_writel(reg, UTMIP_PLL_CFG2);
869
870 /* Program UTMIP PLL delay and oscillator frequency counts */
871 reg = clk_readl(UTMIP_PLL_CFG1);
872 reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
873
874 reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
875 utmi_parameters[i].enable_delay_count);
876
877 reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
878 reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
879 utmi_parameters[i].xtal_freq_count);
880
881 /* Remove power downs from UTMIP PLL control bits */
882 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
883 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
884 reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
885
886 clk_writel(reg, UTMIP_PLL_CFG1);
887}
888
889static void tegra30_pll_clk_init(struct clk *c)
890{
891 u32 val = clk_readl(c->reg + PLL_BASE);
892
893 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
894
895 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
896 const struct clk_pll_freq_table *sel;
897 unsigned long input_rate = clk_get_rate(c->parent);
898 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
899 if (sel->input_rate == input_rate &&
900 sel->output_rate == c->u.pll.fixed_rate) {
901 c->mul = sel->n;
902 c->div = sel->m * sel->p;
903 return;
904 }
905 }
906 pr_err("Clock %s has unknown fixed frequency\n", c->name);
907 BUG();
908 } else if (val & PLL_BASE_BYPASS) {
909 c->mul = 1;
910 c->div = 1;
911 } else {
912 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
913 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
914 if (c->flags & PLLU)
915 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
916 else
917 c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
918 PLL_BASE_DIVP_SHIFT));
919 if (c->flags & PLL_FIXED) {
920 unsigned long rate = clk_get_rate_locked(c);
921 BUG_ON(rate != c->u.pll.fixed_rate);
922 }
923 }
924
925 if (c->flags & PLLU)
926 tegra30_utmi_param_configure(c);
927}
928
929static int tegra30_pll_clk_enable(struct clk *c)
930{
931 u32 val;
932 pr_debug("%s on clock %s\n", __func__, c->name);
933
934#if USE_PLL_LOCK_BITS
935 val = clk_readl(c->reg + PLL_MISC(c));
936 val |= PLL_MISC_LOCK_ENABLE(c);
937 clk_writel(val, c->reg + PLL_MISC(c));
938#endif
939 val = clk_readl(c->reg + PLL_BASE);
940 val &= ~PLL_BASE_BYPASS;
941 val |= PLL_BASE_ENABLE;
942 clk_writel(val, c->reg + PLL_BASE);
943
944 if (c->flags & PLLM) {
945 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
946 val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
947 pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
948 }
949
950 tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK);
951
952 return 0;
953}
954
955static void tegra30_pll_clk_disable(struct clk *c)
956{
957 u32 val;
958 pr_debug("%s on clock %s\n", __func__, c->name);
959
960 val = clk_readl(c->reg);
961 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
962 clk_writel(val, c->reg);
963
964 if (c->flags & PLLM) {
965 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
966 val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
967 pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
968 }
969}
970
971static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
972{
973 u32 val, p_div, old_base;
974 unsigned long input_rate;
975 const struct clk_pll_freq_table *sel;
976 struct clk_pll_freq_table cfg;
977
978 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
979
980 if (c->flags & PLL_FIXED) {
981 int ret = 0;
982 if (rate != c->u.pll.fixed_rate) {
983 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
984 __func__, c->name, c->u.pll.fixed_rate, rate);
985 ret = -EINVAL;
986 }
987 return ret;
988 }
989
990 if (c->flags & PLLM) {
991 if (rate != clk_get_rate_locked(c)) {
992 pr_err("%s: Can not change memory %s rate in flight\n",
993 __func__, c->name);
994 return -EINVAL;
995 }
996 return 0;
997 }
998
999 p_div = 0;
1000 input_rate = clk_get_rate(c->parent);
1001
1002 /* Check if the target rate is tabulated */
1003 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1004 if (sel->input_rate == input_rate && sel->output_rate == rate) {
1005 if (c->flags & PLLU) {
1006 BUG_ON(sel->p < 1 || sel->p > 2);
1007 if (sel->p == 1)
1008 p_div = PLLU_BASE_POST_DIV;
1009 } else {
1010 BUG_ON(sel->p < 1);
1011 for (val = sel->p; val > 1; val >>= 1)
1012 p_div++;
1013 p_div <<= PLL_BASE_DIVP_SHIFT;
1014 }
1015 break;
1016 }
1017 }
1018
1019 /* Configure out-of-table rate */
1020 if (sel->input_rate == 0) {
1021 unsigned long cfreq;
1022 BUG_ON(c->flags & PLLU);
1023 sel = &cfg;
1024
1025 switch (input_rate) {
1026 case 12000000:
1027 case 26000000:
1028 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
1029 break;
1030 case 13000000:
1031 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
1032 break;
1033 case 16800000:
1034 case 19200000:
1035 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
1036 break;
1037 default:
1038 pr_err("%s: Unexpected reference rate %lu\n",
1039 __func__, input_rate);
1040 BUG();
1041 }
1042
1043 /* Raise VCO to guarantee 0.5% accuracy */
1044 for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
1045 cfg.output_rate <<= 1)
1046 p_div++;
1047
1048 cfg.p = 0x1 << p_div;
1049 cfg.m = input_rate / cfreq;
1050 cfg.n = cfg.output_rate / cfreq;
1051 cfg.cpcon = OUT_OF_TABLE_CPCON;
1052
1053 if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
1054 (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
1055 (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
1056 (cfg.output_rate > c->u.pll.vco_max)) {
1057 pr_err("%s: Failed to set %s out-of-table rate %lu\n",
1058 __func__, c->name, rate);
1059 return -EINVAL;
1060 }
1061 p_div <<= PLL_BASE_DIVP_SHIFT;
1062 }
1063
1064 c->mul = sel->n;
1065 c->div = sel->m * sel->p;
1066
1067 old_base = val = clk_readl(c->reg + PLL_BASE);
1068 val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
1069 ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
1070 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
1071 (sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
1072 if (val == old_base)
1073 return 0;
1074
1075 if (c->state == ON) {
1076 tegra30_pll_clk_disable(c);
1077 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
1078 }
1079 clk_writel(val, c->reg + PLL_BASE);
1080
1081 if (c->flags & PLL_HAS_CPCON) {
1082 val = clk_readl(c->reg + PLL_MISC(c));
1083 val &= ~PLL_MISC_CPCON_MASK;
1084 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
1085 if (c->flags & (PLLU | PLLD)) {
1086 val &= ~PLL_MISC_LFCON_MASK;
1087 if (sel->n >= PLLDU_LFCON_SET_DIVN)
1088 val |= 0x1 << PLL_MISC_LFCON_SHIFT;
1089 } else if (c->flags & (PLLX | PLLM)) {
1090 val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
1091 if (rate >= (c->u.pll.vco_max >> 1))
1092 val |= 0x1 << PLL_MISC_DCCON_SHIFT;
1093 }
1094 clk_writel(val, c->reg + PLL_MISC(c));
1095 }
1096
1097 if (c->state == ON)
1098 tegra30_pll_clk_enable(c);
1099
1100 return 0;
1101}
1102
1103static struct clk_ops tegra_pll_ops = {
1104 .init = tegra30_pll_clk_init,
1105 .enable = tegra30_pll_clk_enable,
1106 .disable = tegra30_pll_clk_disable,
1107 .set_rate = tegra30_pll_clk_set_rate,
1108};
1109
1110static int
1111tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
1112{
1113 u32 val, mask, reg;
1114
1115 switch (p) {
1116 case TEGRA_CLK_PLLD_CSI_OUT_ENB:
1117 mask = PLLD_BASE_CSI_CLKENABLE;
1118 reg = c->reg + PLL_BASE;
1119 break;
1120 case TEGRA_CLK_PLLD_DSI_OUT_ENB:
1121 mask = PLLD_MISC_DSI_CLKENABLE;
1122 reg = c->reg + PLL_MISC(c);
1123 break;
1124 case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
1125 if (!(c->flags & PLL_ALT_MISC_REG)) {
1126 mask = PLLD_BASE_DSIB_MUX_MASK;
1127 reg = c->reg + PLL_BASE;
1128 break;
1129 }
1130 /* fall through - error since PLLD2 does not have MUX_SEL control */
1131 default:
1132 return -EINVAL;
1133 }
1134
1135 val = clk_readl(reg);
1136 if (setting)
1137 val |= mask;
1138 else
1139 val &= ~mask;
1140 clk_writel(val, reg);
1141 return 0;
1142}
1143
1144static struct clk_ops tegra_plld_ops = {
1145 .init = tegra30_pll_clk_init,
1146 .enable = tegra30_pll_clk_enable,
1147 .disable = tegra30_pll_clk_disable,
1148 .set_rate = tegra30_pll_clk_set_rate,
1149 .clk_cfg_ex = tegra30_plld_clk_cfg_ex,
1150};
1151
1152static void tegra30_plle_clk_init(struct clk *c)
1153{
1154 u32 val;
1155
1156 val = clk_readl(PLLE_AUX);
1157 c->parent = (val & PLLE_AUX_PLLP_SEL) ?
1158 tegra_get_clock_by_name("pll_p") :
1159 tegra_get_clock_by_name("pll_ref");
1160
1161 val = clk_readl(c->reg + PLL_BASE);
1162 c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
1163 c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
1164 c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
1165 c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
1166}
1167
1168static void tegra30_plle_clk_disable(struct clk *c)
1169{
1170 u32 val;
1171 pr_debug("%s on clock %s\n", __func__, c->name);
1172
1173 val = clk_readl(c->reg + PLL_BASE);
1174 val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
1175 clk_writel(val, c->reg + PLL_BASE);
1176}
1177
1178static void tegra30_plle_training(struct clk *c)
1179{
1180 u32 val;
1181
1182 /* PLLE is already disabled, and setup cleared;
1183 * create falling edge on PLLE IDDQ input */
1184 val = pmc_readl(PMC_SATA_PWRGT);
1185 val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
1186 pmc_writel(val, PMC_SATA_PWRGT);
1187
1188 val = pmc_readl(PMC_SATA_PWRGT);
1189 val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
1190 pmc_writel(val, PMC_SATA_PWRGT);
1191
1192 val = pmc_readl(PMC_SATA_PWRGT);
1193 val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
1194 pmc_writel(val, PMC_SATA_PWRGT);
1195
1196 do {
1197 val = clk_readl(c->reg + PLL_MISC(c));
1198 } while (!(val & PLLE_MISC_READY));
1199}
1200
1201static int tegra30_plle_configure(struct clk *c, bool force_training)
1202{
1203 u32 val;
1204 const struct clk_pll_freq_table *sel;
1205 unsigned long rate = c->u.pll.fixed_rate;
1206 unsigned long input_rate = clk_get_rate(c->parent);
1207
1208 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1209 if (sel->input_rate == input_rate && sel->output_rate == rate)
1210 break;
1211 }
1212
1213 if (sel->input_rate == 0)
1214 return -ENOSYS;
1215
1216 /* disable PLLE, clear setup fiels */
1217 tegra30_plle_clk_disable(c);
1218
1219 val = clk_readl(c->reg + PLL_MISC(c));
1220 val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
1221 clk_writel(val, c->reg + PLL_MISC(c));
1222
1223 /* training */
1224 val = clk_readl(c->reg + PLL_MISC(c));
1225 if (force_training || (!(val & PLLE_MISC_READY)))
1226 tegra30_plle_training(c);
1227
1228 /* configure dividers, setup, disable SS */
1229 val = clk_readl(c->reg + PLL_BASE);
1230 val &= ~PLLE_BASE_DIV_MASK;
1231 val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon);
1232 clk_writel(val, c->reg + PLL_BASE);
1233 c->mul = sel->n;
1234 c->div = sel->m * sel->p;
1235
1236 val = clk_readl(c->reg + PLL_MISC(c));
1237 val |= PLLE_MISC_SETUP_VALUE;
1238 val |= PLLE_MISC_LOCK_ENABLE;
1239 clk_writel(val, c->reg + PLL_MISC(c));
1240
1241 val = clk_readl(PLLE_SS_CTRL);
1242 val |= PLLE_SS_DISABLE;
1243 clk_writel(val, PLLE_SS_CTRL);
1244
1245 /* enable and lock PLLE*/
1246 val = clk_readl(c->reg + PLL_BASE);
1247 val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
1248 clk_writel(val, c->reg + PLL_BASE);
1249
1250 tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK);
1251
1252 return 0;
1253}
1254
1255static int tegra30_plle_clk_enable(struct clk *c)
1256{
1257 pr_debug("%s on clock %s\n", __func__, c->name);
1258 return tegra30_plle_configure(c, !c->set);
1259}
1260
1261static struct clk_ops tegra_plle_ops = {
1262 .init = tegra30_plle_clk_init,
1263 .enable = tegra30_plle_clk_enable,
1264 .disable = tegra30_plle_clk_disable,
1265};
1266
1267/* Clock divider ops */
1268static void tegra30_pll_div_clk_init(struct clk *c)
1269{
1270 if (c->flags & DIV_U71) {
1271 u32 divu71;
1272 u32 val = clk_readl(c->reg);
1273 val >>= c->reg_shift;
1274 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
1275 if (!(val & PLL_OUT_RESET_DISABLE))
1276 c->state = OFF;
1277
1278 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
1279 c->div = (divu71 + 2);
1280 c->mul = 2;
1281 } else if (c->flags & DIV_2) {
1282 c->state = ON;
1283 if (c->flags & (PLLD | PLLX)) {
1284 c->div = 2;
1285 c->mul = 1;
1286 } else
1287 BUG();
1288 } else {
1289 c->state = ON;
1290 c->div = 1;
1291 c->mul = 1;
1292 }
1293}
1294
1295static int tegra30_pll_div_clk_enable(struct clk *c)
1296{
1297 u32 val;
1298 u32 new_val;
1299
1300 pr_debug("%s: %s\n", __func__, c->name);
1301 if (c->flags & DIV_U71) {
1302 val = clk_readl(c->reg);
1303 new_val = val >> c->reg_shift;
1304 new_val &= 0xFFFF;
1305
1306 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
1307
1308 val &= ~(0xFFFF << c->reg_shift);
1309 val |= new_val << c->reg_shift;
1310 clk_writel_delay(val, c->reg);
1311 return 0;
1312 } else if (c->flags & DIV_2) {
1313 return 0;
1314 }
1315 return -EINVAL;
1316}
1317
1318static void tegra30_pll_div_clk_disable(struct clk *c)
1319{
1320 u32 val;
1321 u32 new_val;
1322
1323 pr_debug("%s: %s\n", __func__, c->name);
1324 if (c->flags & DIV_U71) {
1325 val = clk_readl(c->reg);
1326 new_val = val >> c->reg_shift;
1327 new_val &= 0xFFFF;
1328
1329 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
1330
1331 val &= ~(0xFFFF << c->reg_shift);
1332 val |= new_val << c->reg_shift;
1333 clk_writel_delay(val, c->reg);
1334 }
1335}
1336
1337static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
1338{
1339 u32 val;
1340 u32 new_val;
1341 int divider_u71;
1342 unsigned long parent_rate = clk_get_rate(c->parent);
1343
1344 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1345 if (c->flags & DIV_U71) {
1346 divider_u71 = clk_div71_get_divider(
1347 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1348 if (divider_u71 >= 0) {
1349 val = clk_readl(c->reg);
1350 new_val = val >> c->reg_shift;
1351 new_val &= 0xFFFF;
1352 if (c->flags & DIV_U71_FIXED)
1353 new_val |= PLL_OUT_OVERRIDE;
1354 new_val &= ~PLL_OUT_RATIO_MASK;
1355 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
1356
1357 val &= ~(0xFFFF << c->reg_shift);
1358 val |= new_val << c->reg_shift;
1359 clk_writel_delay(val, c->reg);
1360 c->div = divider_u71 + 2;
1361 c->mul = 2;
1362 return 0;
1363 }
1364 } else if (c->flags & DIV_2)
1365 return clk_set_rate(c->parent, rate * 2);
1366
1367 return -EINVAL;
1368}
1369
1370static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
1371{
1372 int divider;
1373 unsigned long parent_rate = clk_get_rate(c->parent);
1374 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1375
1376 if (c->flags & DIV_U71) {
1377 divider = clk_div71_get_divider(
1378 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1379 if (divider < 0)
1380 return divider;
1381 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1382 } else if (c->flags & DIV_2)
1383 /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */
1384 return rate;
1385
1386 return -EINVAL;
1387}
1388
1389static struct clk_ops tegra_pll_div_ops = {
1390 .init = tegra30_pll_div_clk_init,
1391 .enable = tegra30_pll_div_clk_enable,
1392 .disable = tegra30_pll_div_clk_disable,
1393 .set_rate = tegra30_pll_div_clk_set_rate,
1394 .round_rate = tegra30_pll_div_clk_round_rate,
1395};
1396
1397/* Periph clk ops */
1398static inline u32 periph_clk_source_mask(struct clk *c)
1399{
1400 if (c->flags & MUX8)
1401 return 7 << 29;
1402 else if (c->flags & MUX_PWM)
1403 return 3 << 28;
1404 else if (c->flags & MUX_CLK_OUT)
1405 return 3 << (c->u.periph.clk_num + 4);
1406 else if (c->flags & PLLD)
1407 return PLLD_BASE_DSIB_MUX_MASK;
1408 else
1409 return 3 << 30;
1410}
1411
1412static inline u32 periph_clk_source_shift(struct clk *c)
1413{
1414 if (c->flags & MUX8)
1415 return 29;
1416 else if (c->flags & MUX_PWM)
1417 return 28;
1418 else if (c->flags & MUX_CLK_OUT)
1419 return c->u.periph.clk_num + 4;
1420 else if (c->flags & PLLD)
1421 return PLLD_BASE_DSIB_MUX_SHIFT;
1422 else
1423 return 30;
1424}
1425
1426static void tegra30_periph_clk_init(struct clk *c)
1427{
1428 u32 val = clk_readl(c->reg);
1429 const struct clk_mux_sel *mux = 0;
1430 const struct clk_mux_sel *sel;
1431 if (c->flags & MUX) {
1432 for (sel = c->inputs; sel->input != NULL; sel++) {
1433 if (((val & periph_clk_source_mask(c)) >>
1434 periph_clk_source_shift(c)) == sel->value)
1435 mux = sel;
1436 }
1437 BUG_ON(!mux);
1438
1439 c->parent = mux->input;
1440 } else {
1441 c->parent = c->inputs[0].input;
1442 }
1443
1444 if (c->flags & DIV_U71) {
1445 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
1446 if ((c->flags & DIV_U71_UART) &&
1447 (!(val & PERIPH_CLK_UART_DIV_ENB))) {
1448 divu71 = 0;
1449 }
1450 if (c->flags & DIV_U71_IDLE) {
1451 val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
1452 PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
1453 val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
1454 PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
1455 clk_writel(val, c->reg);
1456 }
1457 c->div = divu71 + 2;
1458 c->mul = 2;
1459 } else if (c->flags & DIV_U16) {
1460 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
1461 c->div = divu16 + 1;
1462 c->mul = 1;
1463 } else {
1464 c->div = 1;
1465 c->mul = 1;
1466 }
1467
1468 c->state = ON;
1469 if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
1470 c->state = OFF;
1471 if (!(c->flags & PERIPH_NO_RESET))
1472 if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
1473 c->state = OFF;
1474}
1475
1476static int tegra30_periph_clk_enable(struct clk *c)
1477{
1478 pr_debug("%s on clock %s\n", __func__, c->name);
1479
1480 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
1481 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
1482 return 0;
1483
1484 clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c));
1485 if (!(c->flags & PERIPH_NO_RESET) &&
1486 !(c->flags & PERIPH_MANUAL_RESET)) {
1487 if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) &
1488 PERIPH_CLK_TO_BIT(c)) {
1489 udelay(5); /* reset propagation delay */
1490 clk_writel(PERIPH_CLK_TO_BIT(c),
1491 PERIPH_CLK_TO_RST_CLR_REG(c));
1492 }
1493 }
1494 return 0;
1495}
1496
1497static void tegra30_periph_clk_disable(struct clk *c)
1498{
1499 unsigned long val;
1500 pr_debug("%s on clock %s\n", __func__, c->name);
1501
1502 if (c->refcnt)
1503 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
1504
1505 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
1506 /* If peripheral is in the APB bus then read the APB bus to
1507 * flush the write operation in apb bus. This will avoid the
1508 * peripheral access after disabling clock*/
1509 if (c->flags & PERIPH_ON_APB)
1510 val = chipid_readl();
1511
1512 clk_writel_delay(
1513 PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
1514 }
1515}
1516
1517static void tegra30_periph_clk_reset(struct clk *c, bool assert)
1518{
1519 unsigned long val;
1520 pr_debug("%s %s on clock %s\n", __func__,
1521 assert ? "assert" : "deassert", c->name);
1522
1523 if (!(c->flags & PERIPH_NO_RESET)) {
1524 if (assert) {
1525 /* If peripheral is in the APB bus then read the APB
1526 * bus to flush the write operation in apb bus. This
1527 * will avoid the peripheral access after disabling
1528 * clock */
1529 if (c->flags & PERIPH_ON_APB)
1530 val = chipid_readl();
1531
1532 clk_writel(PERIPH_CLK_TO_BIT(c),
1533 PERIPH_CLK_TO_RST_SET_REG(c));
1534 } else
1535 clk_writel(PERIPH_CLK_TO_BIT(c),
1536 PERIPH_CLK_TO_RST_CLR_REG(c));
1537 }
1538}
1539
1540static int tegra30_periph_clk_set_parent(struct clk *c, struct clk *p)
1541{
1542 u32 val;
1543 const struct clk_mux_sel *sel;
1544 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
1545
1546 if (!(c->flags & MUX))
1547 return (p == c->parent) ? 0 : (-EINVAL);
1548
1549 for (sel = c->inputs; sel->input != NULL; sel++) {
1550 if (sel->input == p) {
1551 val = clk_readl(c->reg);
1552 val &= ~periph_clk_source_mask(c);
1553 val |= (sel->value << periph_clk_source_shift(c));
1554
1555 if (c->refcnt)
1556 clk_enable(p);
1557
1558 clk_writel_delay(val, c->reg);
1559
1560 if (c->refcnt && c->parent)
1561 clk_disable(c->parent);
1562
1563 clk_reparent(c, p);
1564 return 0;
1565 }
1566 }
1567
1568 return -EINVAL;
1569}
1570
1571static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate)
1572{
1573 u32 val;
1574 int divider;
1575 unsigned long parent_rate = clk_get_rate(c->parent);
1576
1577 if (c->flags & DIV_U71) {
1578 divider = clk_div71_get_divider(
1579 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1580 if (divider >= 0) {
1581 val = clk_readl(c->reg);
1582 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
1583 val |= divider;
1584 if (c->flags & DIV_U71_UART) {
1585 if (divider)
1586 val |= PERIPH_CLK_UART_DIV_ENB;
1587 else
1588 val &= ~PERIPH_CLK_UART_DIV_ENB;
1589 }
1590 clk_writel_delay(val, c->reg);
1591 c->div = divider + 2;
1592 c->mul = 2;
1593 return 0;
1594 }
1595 } else if (c->flags & DIV_U16) {
1596 divider = clk_div16_get_divider(parent_rate, rate);
1597 if (divider >= 0) {
1598 val = clk_readl(c->reg);
1599 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1600 val |= divider;
1601 clk_writel_delay(val, c->reg);
1602 c->div = divider + 1;
1603 c->mul = 1;
1604 return 0;
1605 }
1606 } else if (parent_rate <= rate) {
1607 c->div = 1;
1608 c->mul = 1;
1609 return 0;
1610 }
1611 return -EINVAL;
1612}
1613
1614static long tegra30_periph_clk_round_rate(struct clk *c,
1615 unsigned long rate)
1616{
1617 int divider;
1618 unsigned long parent_rate = clk_get_rate(c->parent);
1619 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
1620
1621 if (c->flags & DIV_U71) {
1622 divider = clk_div71_get_divider(
1623 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1624 if (divider < 0)
1625 return divider;
1626
1627 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1628 } else if (c->flags & DIV_U16) {
1629 divider = clk_div16_get_divider(parent_rate, rate);
1630 if (divider < 0)
1631 return divider;
1632 return DIV_ROUND_UP(parent_rate, divider + 1);
1633 }
1634 return -EINVAL;
1635}
1636
1637static struct clk_ops tegra_periph_clk_ops = {
1638 .init = &tegra30_periph_clk_init,
1639 .enable = &tegra30_periph_clk_enable,
1640 .disable = &tegra30_periph_clk_disable,
1641 .set_parent = &tegra30_periph_clk_set_parent,
1642 .set_rate = &tegra30_periph_clk_set_rate,
1643 .round_rate = &tegra30_periph_clk_round_rate,
1644 .reset = &tegra30_periph_clk_reset,
1645};
1646
1647
1648/* Periph extended clock configuration ops */
1649static int
1650tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
1651{
1652 if (p == TEGRA_CLK_VI_INP_SEL) {
1653 u32 val = clk_readl(c->reg);
1654 val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
1655 val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) &
1656 PERIPH_CLK_VI_SEL_EX_MASK;
1657 clk_writel(val, c->reg);
1658 return 0;
1659 }
1660 return -EINVAL;
1661}
1662
1663static struct clk_ops tegra_vi_clk_ops = {
1664 .init = &tegra30_periph_clk_init,
1665 .enable = &tegra30_periph_clk_enable,
1666 .disable = &tegra30_periph_clk_disable,
1667 .set_parent = &tegra30_periph_clk_set_parent,
1668 .set_rate = &tegra30_periph_clk_set_rate,
1669 .round_rate = &tegra30_periph_clk_round_rate,
1670 .clk_cfg_ex = &tegra30_vi_clk_cfg_ex,
1671 .reset = &tegra30_periph_clk_reset,
1672};
1673
1674static int
1675tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
1676{
1677 if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
1678 u32 val = clk_readl(c->reg);
1679 if (setting)
1680 val |= PERIPH_CLK_NAND_DIV_EX_ENB;
1681 else
1682 val &= ~PERIPH_CLK_NAND_DIV_EX_ENB;
1683 clk_writel(val, c->reg);
1684 return 0;
1685 }
1686 return -EINVAL;
1687}
1688
1689static struct clk_ops tegra_nand_clk_ops = {
1690 .init = &tegra30_periph_clk_init,
1691 .enable = &tegra30_periph_clk_enable,
1692 .disable = &tegra30_periph_clk_disable,
1693 .set_parent = &tegra30_periph_clk_set_parent,
1694 .set_rate = &tegra30_periph_clk_set_rate,
1695 .round_rate = &tegra30_periph_clk_round_rate,
1696 .clk_cfg_ex = &tegra30_nand_clk_cfg_ex,
1697 .reset = &tegra30_periph_clk_reset,
1698};
1699
1700
1701static int
1702tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
1703{
1704 if (p == TEGRA_CLK_DTV_INVERT) {
1705 u32 val = clk_readl(c->reg);
1706 if (setting)
1707 val |= PERIPH_CLK_DTV_POLARITY_INV;
1708 else
1709 val &= ~PERIPH_CLK_DTV_POLARITY_INV;
1710 clk_writel(val, c->reg);
1711 return 0;
1712 }
1713 return -EINVAL;
1714}
1715
1716static struct clk_ops tegra_dtv_clk_ops = {
1717 .init = &tegra30_periph_clk_init,
1718 .enable = &tegra30_periph_clk_enable,
1719 .disable = &tegra30_periph_clk_disable,
1720 .set_parent = &tegra30_periph_clk_set_parent,
1721 .set_rate = &tegra30_periph_clk_set_rate,
1722 .round_rate = &tegra30_periph_clk_round_rate,
1723 .clk_cfg_ex = &tegra30_dtv_clk_cfg_ex,
1724 .reset = &tegra30_periph_clk_reset,
1725};
1726
1727static int tegra30_dsib_clk_set_parent(struct clk *c, struct clk *p)
1728{
1729 const struct clk_mux_sel *sel;
1730 struct clk *d = tegra_get_clock_by_name("pll_d");
1731
1732 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
1733
1734 for (sel = c->inputs; sel->input != NULL; sel++) {
1735 if (sel->input == p) {
1736 if (c->refcnt)
1737 clk_enable(p);
1738
1739 /* The DSIB parent selection bit is in PLLD base
1740 register - can not do direct r-m-w, must be
1741 protected by PLLD lock */
1742 tegra_clk_cfg_ex(
1743 d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value);
1744
1745 if (c->refcnt && c->parent)
1746 clk_disable(c->parent);
1747
1748 clk_reparent(c, p);
1749 return 0;
1750 }
1751 }
1752
1753 return -EINVAL;
1754}
1755
1756static struct clk_ops tegra_dsib_clk_ops = {
1757 .init = &tegra30_periph_clk_init,
1758 .enable = &tegra30_periph_clk_enable,
1759 .disable = &tegra30_periph_clk_disable,
1760 .set_parent = &tegra30_dsib_clk_set_parent,
1761 .set_rate = &tegra30_periph_clk_set_rate,
1762 .round_rate = &tegra30_periph_clk_round_rate,
1763 .reset = &tegra30_periph_clk_reset,
1764};
1765
1766/* pciex clock support only reset function */
1767static struct clk_ops tegra_pciex_clk_ops = {
1768 .reset = tegra30_periph_clk_reset,
1769};
1770
1771/* Output clock ops */
1772
1773static DEFINE_SPINLOCK(clk_out_lock);
1774
1775static void tegra30_clk_out_init(struct clk *c)
1776{
1777 const struct clk_mux_sel *mux = 0;
1778 const struct clk_mux_sel *sel;
1779 u32 val = pmc_readl(c->reg);
1780
1781 c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
1782 c->mul = 1;
1783 c->div = 1;
1784
1785 for (sel = c->inputs; sel->input != NULL; sel++) {
1786 if (((val & periph_clk_source_mask(c)) >>
1787 periph_clk_source_shift(c)) == sel->value)
1788 mux = sel;
1789 }
1790 BUG_ON(!mux);
1791 c->parent = mux->input;
1792}
1793
1794static int tegra30_clk_out_enable(struct clk *c)
1795{
1796 u32 val;
1797 unsigned long flags;
1798
1799 pr_debug("%s on clock %s\n", __func__, c->name);
1800
1801 spin_lock_irqsave(&clk_out_lock, flags);
1802 val = pmc_readl(c->reg);
1803 val |= (0x1 << c->u.periph.clk_num);
1804 pmc_writel(val, c->reg);
1805 spin_unlock_irqrestore(&clk_out_lock, flags);
1806
1807 return 0;
1808}
1809
1810static void tegra30_clk_out_disable(struct clk *c)
1811{
1812 u32 val;
1813 unsigned long flags;
1814
1815 pr_debug("%s on clock %s\n", __func__, c->name);
1816
1817 spin_lock_irqsave(&clk_out_lock, flags);
1818 val = pmc_readl(c->reg);
1819 val &= ~(0x1 << c->u.periph.clk_num);
1820 pmc_writel(val, c->reg);
1821 spin_unlock_irqrestore(&clk_out_lock, flags);
1822}
1823
1824static int tegra30_clk_out_set_parent(struct clk *c, struct clk *p)
1825{
1826 u32 val;
1827 unsigned long flags;
1828 const struct clk_mux_sel *sel;
1829
1830 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
1831
1832 for (sel = c->inputs; sel->input != NULL; sel++) {
1833 if (sel->input == p) {
1834 if (c->refcnt)
1835 clk_enable(p);
1836
1837 spin_lock_irqsave(&clk_out_lock, flags);
1838 val = pmc_readl(c->reg);
1839 val &= ~periph_clk_source_mask(c);
1840 val |= (sel->value << periph_clk_source_shift(c));
1841 pmc_writel(val, c->reg);
1842 spin_unlock_irqrestore(&clk_out_lock, flags);
1843
1844 if (c->refcnt && c->parent)
1845 clk_disable(c->parent);
1846
1847 clk_reparent(c, p);
1848 return 0;
1849 }
1850 }
1851 return -EINVAL;
1852}
1853
1854static struct clk_ops tegra_clk_out_ops = {
1855 .init = &tegra30_clk_out_init,
1856 .enable = &tegra30_clk_out_enable,
1857 .disable = &tegra30_clk_out_disable,
1858 .set_parent = &tegra30_clk_out_set_parent,
1859};
1860
1861
1862/* Clock doubler ops */
1863static void tegra30_clk_double_init(struct clk *c)
1864{
1865 u32 val = clk_readl(c->reg);
1866 c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
1867 c->div = 1;
1868 c->state = ON;
1869 if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
1870 c->state = OFF;
1871};
1872
1873static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate)
1874{
1875 u32 val;
1876 unsigned long parent_rate = clk_get_rate(c->parent);
1877 if (rate == parent_rate) {
1878 val = clk_readl(c->reg) | (0x1 << c->reg_shift);
1879 clk_writel(val, c->reg);
1880 c->mul = 1;
1881 c->div = 1;
1882 return 0;
1883 } else if (rate == 2 * parent_rate) {
1884 val = clk_readl(c->reg) & (~(0x1 << c->reg_shift));
1885 clk_writel(val, c->reg);
1886 c->mul = 2;
1887 c->div = 1;
1888 return 0;
1889 }
1890 return -EINVAL;
1891}
1892
1893static struct clk_ops tegra_clk_double_ops = {
1894 .init = &tegra30_clk_double_init,
1895 .enable = &tegra30_periph_clk_enable,
1896 .disable = &tegra30_periph_clk_disable,
1897 .set_rate = &tegra30_clk_double_set_rate,
1898};
1899
1900/* Audio sync clock ops */
1901static int tegra30_sync_source_set_rate(struct clk *c, unsigned long rate)
1902{
1903 c->rate = rate;
1904 return 0;
1905}
1906
1907static struct clk_ops tegra_sync_source_ops = {
1908 .set_rate = &tegra30_sync_source_set_rate,
1909};
1910
1911static void tegra30_audio_sync_clk_init(struct clk *c)
1912{
1913 int source;
1914 const struct clk_mux_sel *sel;
1915 u32 val = clk_readl(c->reg);
1916 c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
1917 source = val & AUDIO_SYNC_SOURCE_MASK;
1918 for (sel = c->inputs; sel->input != NULL; sel++)
1919 if (sel->value == source)
1920 break;
1921 BUG_ON(sel->input == NULL);
1922 c->parent = sel->input;
1923}
1924
1925static int tegra30_audio_sync_clk_enable(struct clk *c)
1926{
1927 u32 val = clk_readl(c->reg);
1928 clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
1929 return 0;
1930}
1931
1932static void tegra30_audio_sync_clk_disable(struct clk *c)
1933{
1934 u32 val = clk_readl(c->reg);
1935 clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
1936}
1937
1938static int tegra30_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
1939{
1940 u32 val;
1941 const struct clk_mux_sel *sel;
1942 for (sel = c->inputs; sel->input != NULL; sel++) {
1943 if (sel->input == p) {
1944 val = clk_readl(c->reg);
1945 val &= ~AUDIO_SYNC_SOURCE_MASK;
1946 val |= sel->value;
1947
1948 if (c->refcnt)
1949 clk_enable(p);
1950
1951 clk_writel(val, c->reg);
1952
1953 if (c->refcnt && c->parent)
1954 clk_disable(c->parent);
1955
1956 clk_reparent(c, p);
1957 return 0;
1958 }
1959 }
1960
1961 return -EINVAL;
1962}
1963
1964static struct clk_ops tegra_audio_sync_clk_ops = {
1965 .init = tegra30_audio_sync_clk_init,
1966 .enable = tegra30_audio_sync_clk_enable,
1967 .disable = tegra30_audio_sync_clk_disable,
1968 .set_parent = tegra30_audio_sync_clk_set_parent,
1969};
1970
1971/* cml0 (pcie), and cml1 (sata) clock ops */
1972static void tegra30_cml_clk_init(struct clk *c)
1973{
1974 u32 val = clk_readl(c->reg);
1975 c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
1976}
1977
1978static int tegra30_cml_clk_enable(struct clk *c)
1979{
1980 u32 val = clk_readl(c->reg);
1981 val |= (0x1 << c->u.periph.clk_num);
1982 clk_writel(val, c->reg);
1983 return 0;
1984}
1985
1986static void tegra30_cml_clk_disable(struct clk *c)
1987{
1988 u32 val = clk_readl(c->reg);
1989 val &= ~(0x1 << c->u.periph.clk_num);
1990 clk_writel(val, c->reg);
1991}
1992
1993static struct clk_ops tegra_cml_clk_ops = {
1994 .init = &tegra30_cml_clk_init,
1995 .enable = &tegra30_cml_clk_enable,
1996 .disable = &tegra30_cml_clk_disable,
1997};
1998
1999/* Clock definitions */
2000static struct clk tegra_clk_32k = {
2001 .name = "clk_32k",
2002 .rate = 32768,
2003 .ops = NULL,
2004 .max_rate = 32768,
2005};
2006
2007static struct clk tegra_clk_m = {
2008 .name = "clk_m",
2009 .flags = ENABLE_ON_INIT,
2010 .ops = &tegra_clk_m_ops,
2011 .reg = 0x1fc,
2012 .reg_shift = 28,
2013 .max_rate = 48000000,
2014};
2015
2016static struct clk tegra_clk_m_div2 = {
2017 .name = "clk_m_div2",
2018 .ops = &tegra_clk_m_div_ops,
2019 .parent = &tegra_clk_m,
2020 .mul = 1,
2021 .div = 2,
2022 .state = ON,
2023 .max_rate = 24000000,
2024};
2025
2026static struct clk tegra_clk_m_div4 = {
2027 .name = "clk_m_div4",
2028 .ops = &tegra_clk_m_div_ops,
2029 .parent = &tegra_clk_m,
2030 .mul = 1,
2031 .div = 4,
2032 .state = ON,
2033 .max_rate = 12000000,
2034};
2035
2036static struct clk tegra_pll_ref = {
2037 .name = "pll_ref",
2038 .flags = ENABLE_ON_INIT,
2039 .ops = &tegra_pll_ref_ops,
2040 .parent = &tegra_clk_m,
2041 .max_rate = 26000000,
2042};
2043
2044static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
2045 { 12000000, 1040000000, 520, 6, 1, 8},
2046 { 13000000, 1040000000, 480, 6, 1, 8},
2047 { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */
2048 { 19200000, 1040000000, 325, 6, 1, 6},
2049 { 26000000, 1040000000, 520, 13, 1, 8},
2050
2051 { 12000000, 832000000, 416, 6, 1, 8},
2052 { 13000000, 832000000, 832, 13, 1, 8},
2053 { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */
2054 { 19200000, 832000000, 260, 6, 1, 8},
2055 { 26000000, 832000000, 416, 13, 1, 8},
2056
2057 { 12000000, 624000000, 624, 12, 1, 8},
2058 { 13000000, 624000000, 624, 13, 1, 8},
2059 { 16800000, 600000000, 520, 14, 1, 8},
2060 { 19200000, 624000000, 520, 16, 1, 8},
2061 { 26000000, 624000000, 624, 26, 1, 8},
2062
2063 { 12000000, 600000000, 600, 12, 1, 8},
2064 { 13000000, 600000000, 600, 13, 1, 8},
2065 { 16800000, 600000000, 500, 14, 1, 8},
2066 { 19200000, 600000000, 375, 12, 1, 6},
2067 { 26000000, 600000000, 600, 26, 1, 8},
2068
2069 { 12000000, 520000000, 520, 12, 1, 8},
2070 { 13000000, 520000000, 520, 13, 1, 8},
2071 { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */
2072 { 19200000, 520000000, 325, 12, 1, 6},
2073 { 26000000, 520000000, 520, 26, 1, 8},
2074
2075 { 12000000, 416000000, 416, 12, 1, 8},
2076 { 13000000, 416000000, 416, 13, 1, 8},
2077 { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */
2078 { 19200000, 416000000, 260, 12, 1, 6},
2079 { 26000000, 416000000, 416, 26, 1, 8},
2080 { 0, 0, 0, 0, 0, 0 },
2081};
2082
2083static struct clk tegra_pll_c = {
2084 .name = "pll_c",
2085 .flags = PLL_HAS_CPCON,
2086 .ops = &tegra_pll_ops,
2087 .reg = 0x80,
2088 .parent = &tegra_pll_ref,
2089 .max_rate = 1400000000,
2090 .u.pll = {
2091 .input_min = 2000000,
2092 .input_max = 31000000,
2093 .cf_min = 1000000,
2094 .cf_max = 6000000,
2095 .vco_min = 20000000,
2096 .vco_max = 1400000000,
2097 .freq_table = tegra_pll_c_freq_table,
2098 .lock_delay = 300,
2099 },
2100};
2101
2102static struct clk tegra_pll_c_out1 = {
2103 .name = "pll_c_out1",
2104 .ops = &tegra_pll_div_ops,
2105 .flags = DIV_U71,
2106 .parent = &tegra_pll_c,
2107 .reg = 0x84,
2108 .reg_shift = 0,
2109 .max_rate = 700000000,
2110};
2111
2112static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
2113 { 12000000, 666000000, 666, 12, 1, 8},
2114 { 13000000, 666000000, 666, 13, 1, 8},
2115 { 16800000, 666000000, 555, 14, 1, 8},
2116 { 19200000, 666000000, 555, 16, 1, 8},
2117 { 26000000, 666000000, 666, 26, 1, 8},
2118 { 12000000, 600000000, 600, 12, 1, 8},
2119 { 13000000, 600000000, 600, 13, 1, 8},
2120 { 16800000, 600000000, 500, 14, 1, 8},
2121 { 19200000, 600000000, 375, 12, 1, 6},
2122 { 26000000, 600000000, 600, 26, 1, 8},
2123 { 0, 0, 0, 0, 0, 0 },
2124};
2125
2126static struct clk tegra_pll_m = {
2127 .name = "pll_m",
2128 .flags = PLL_HAS_CPCON | PLLM,
2129 .ops = &tegra_pll_ops,
2130 .reg = 0x90,
2131 .parent = &tegra_pll_ref,
2132 .max_rate = 800000000,
2133 .u.pll = {
2134 .input_min = 2000000,
2135 .input_max = 31000000,
2136 .cf_min = 1000000,
2137 .cf_max = 6000000,
2138 .vco_min = 20000000,
2139 .vco_max = 1200000000,
2140 .freq_table = tegra_pll_m_freq_table,
2141 .lock_delay = 300,
2142 },
2143};
2144
2145static struct clk tegra_pll_m_out1 = {
2146 .name = "pll_m_out1",
2147 .ops = &tegra_pll_div_ops,
2148 .flags = DIV_U71,
2149 .parent = &tegra_pll_m,
2150 .reg = 0x94,
2151 .reg_shift = 0,
2152 .max_rate = 600000000,
2153};
2154
2155static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
2156 { 12000000, 216000000, 432, 12, 2, 8},
2157 { 13000000, 216000000, 432, 13, 2, 8},
2158 { 16800000, 216000000, 360, 14, 2, 8},
2159 { 19200000, 216000000, 360, 16, 2, 8},
2160 { 26000000, 216000000, 432, 26, 2, 8},
2161 { 0, 0, 0, 0, 0, 0 },
2162};
2163
2164static struct clk tegra_pll_p = {
2165 .name = "pll_p",
2166 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
2167 .ops = &tegra_pll_ops,
2168 .reg = 0xa0,
2169 .parent = &tegra_pll_ref,
2170 .max_rate = 432000000,
2171 .u.pll = {
2172 .input_min = 2000000,
2173 .input_max = 31000000,
2174 .cf_min = 1000000,
2175 .cf_max = 6000000,
2176 .vco_min = 20000000,
2177 .vco_max = 1400000000,
2178 .freq_table = tegra_pll_p_freq_table,
2179 .lock_delay = 300,
2180 .fixed_rate = 408000000,
2181 },
2182};
2183
2184static struct clk tegra_pll_p_out1 = {
2185 .name = "pll_p_out1",
2186 .ops = &tegra_pll_div_ops,
2187 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
2188 .parent = &tegra_pll_p,
2189 .reg = 0xa4,
2190 .reg_shift = 0,
2191 .max_rate = 432000000,
2192};
2193
2194static struct clk tegra_pll_p_out2 = {
2195 .name = "pll_p_out2",
2196 .ops = &tegra_pll_div_ops,
2197 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
2198 .parent = &tegra_pll_p,
2199 .reg = 0xa4,
2200 .reg_shift = 16,
2201 .max_rate = 432000000,
2202};
2203
2204static struct clk tegra_pll_p_out3 = {
2205 .name = "pll_p_out3",
2206 .ops = &tegra_pll_div_ops,
2207 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
2208 .parent = &tegra_pll_p,
2209 .reg = 0xa8,
2210 .reg_shift = 0,
2211 .max_rate = 432000000,
2212};
2213
2214static struct clk tegra_pll_p_out4 = {
2215 .name = "pll_p_out4",
2216 .ops = &tegra_pll_div_ops,
2217 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
2218 .parent = &tegra_pll_p,
2219 .reg = 0xa8,
2220 .reg_shift = 16,
2221 .max_rate = 432000000,
2222};
2223
2224static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
2225 { 9600000, 564480000, 294, 5, 1, 4},
2226 { 9600000, 552960000, 288, 5, 1, 4},
2227 { 9600000, 24000000, 5, 2, 1, 1},
2228
2229 { 28800000, 56448000, 49, 25, 1, 1},
2230 { 28800000, 73728000, 64, 25, 1, 1},
2231 { 28800000, 24000000, 5, 6, 1, 1},
2232 { 0, 0, 0, 0, 0, 0 },
2233};
2234
2235static struct clk tegra_pll_a = {
2236 .name = "pll_a",
2237 .flags = PLL_HAS_CPCON,
2238 .ops = &tegra_pll_ops,
2239 .reg = 0xb0,
2240 .parent = &tegra_pll_p_out1,
2241 .max_rate = 700000000,
2242 .u.pll = {
2243 .input_min = 2000000,
2244 .input_max = 31000000,
2245 .cf_min = 1000000,
2246 .cf_max = 6000000,
2247 .vco_min = 20000000,
2248 .vco_max = 1400000000,
2249 .freq_table = tegra_pll_a_freq_table,
2250 .lock_delay = 300,
2251 },
2252};
2253
2254static struct clk tegra_pll_a_out0 = {
2255 .name = "pll_a_out0",
2256 .ops = &tegra_pll_div_ops,
2257 .flags = DIV_U71,
2258 .parent = &tegra_pll_a,
2259 .reg = 0xb4,
2260 .reg_shift = 0,
2261 .max_rate = 100000000,
2262};
2263
2264static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
2265 { 12000000, 216000000, 216, 12, 1, 4},
2266 { 13000000, 216000000, 216, 13, 1, 4},
2267 { 16800000, 216000000, 180, 14, 1, 4},
2268 { 19200000, 216000000, 180, 16, 1, 4},
2269 { 26000000, 216000000, 216, 26, 1, 4},
2270
2271 { 12000000, 594000000, 594, 12, 1, 8},
2272 { 13000000, 594000000, 594, 13, 1, 8},
2273 { 16800000, 594000000, 495, 14, 1, 8},
2274 { 19200000, 594000000, 495, 16, 1, 8},
2275 { 26000000, 594000000, 594, 26, 1, 8},
2276
2277 { 12000000, 1000000000, 1000, 12, 1, 12},
2278 { 13000000, 1000000000, 1000, 13, 1, 12},
2279 { 19200000, 1000000000, 625, 12, 1, 8},
2280 { 26000000, 1000000000, 1000, 26, 1, 12},
2281
2282 { 0, 0, 0, 0, 0, 0 },
2283};
2284
2285static struct clk tegra_pll_d = {
2286 .name = "pll_d",
2287 .flags = PLL_HAS_CPCON | PLLD,
2288 .ops = &tegra_plld_ops,
2289 .reg = 0xd0,
2290 .parent = &tegra_pll_ref,
2291 .max_rate = 1000000000,
2292 .u.pll = {
2293 .input_min = 2000000,
2294 .input_max = 40000000,
2295 .cf_min = 1000000,
2296 .cf_max = 6000000,
2297 .vco_min = 40000000,
2298 .vco_max = 1000000000,
2299 .freq_table = tegra_pll_d_freq_table,
2300 .lock_delay = 1000,
2301 },
2302};
2303
2304static struct clk tegra_pll_d_out0 = {
2305 .name = "pll_d_out0",
2306 .ops = &tegra_pll_div_ops,
2307 .flags = DIV_2 | PLLD,
2308 .parent = &tegra_pll_d,
2309 .max_rate = 500000000,
2310};
2311
2312static struct clk tegra_pll_d2 = {
2313 .name = "pll_d2",
2314 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD,
2315 .ops = &tegra_plld_ops,
2316 .reg = 0x4b8,
2317 .parent = &tegra_pll_ref,
2318 .max_rate = 1000000000,
2319 .u.pll = {
2320 .input_min = 2000000,
2321 .input_max = 40000000,
2322 .cf_min = 1000000,
2323 .cf_max = 6000000,
2324 .vco_min = 40000000,
2325 .vco_max = 1000000000,
2326 .freq_table = tegra_pll_d_freq_table,
2327 .lock_delay = 1000,
2328 },
2329};
2330
2331static struct clk tegra_pll_d2_out0 = {
2332 .name = "pll_d2_out0",
2333 .ops = &tegra_pll_div_ops,
2334 .flags = DIV_2 | PLLD,
2335 .parent = &tegra_pll_d2,
2336 .max_rate = 500000000,
2337};
2338
2339static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
2340 { 12000000, 480000000, 960, 12, 2, 12},
2341 { 13000000, 480000000, 960, 13, 2, 12},
2342 { 16800000, 480000000, 400, 7, 2, 5},
2343 { 19200000, 480000000, 200, 4, 2, 3},
2344 { 26000000, 480000000, 960, 26, 2, 12},
2345 { 0, 0, 0, 0, 0, 0 },
2346};
2347
2348static struct clk tegra_pll_u = {
2349 .name = "pll_u",
2350 .flags = PLL_HAS_CPCON | PLLU,
2351 .ops = &tegra_pll_ops,
2352 .reg = 0xc0,
2353 .parent = &tegra_pll_ref,
2354 .max_rate = 480000000,
2355 .u.pll = {
2356 .input_min = 2000000,
2357 .input_max = 40000000,
2358 .cf_min = 1000000,
2359 .cf_max = 6000000,
2360 .vco_min = 480000000,
2361 .vco_max = 960000000,
2362 .freq_table = tegra_pll_u_freq_table,
2363 .lock_delay = 1000,
2364 },
2365};
2366
2367static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
2368 /* 1.7 GHz */
2369 { 12000000, 1700000000, 850, 6, 1, 8},
2370 { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */
2371 { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */
2372 { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */
2373 { 26000000, 1700000000, 850, 13, 1, 8},
2374
2375 /* 1.6 GHz */
2376 { 12000000, 1600000000, 800, 6, 1, 8},
2377 { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */
2378 { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */
2379 { 19200000, 1600000000, 500, 6, 1, 8},
2380 { 26000000, 1600000000, 800, 13, 1, 8},
2381
2382 /* 1.5 GHz */
2383 { 12000000, 1500000000, 750, 6, 1, 8},
2384 { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */
2385 { 16800000, 1500000000, 625, 7, 1, 8},
2386 { 19200000, 1500000000, 625, 8, 1, 8},
2387 { 26000000, 1500000000, 750, 13, 1, 8},
2388
2389 /* 1.4 GHz */
2390 { 12000000, 1400000000, 700, 6, 1, 8},
2391 { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */
2392 { 16800000, 1400000000, 1000, 12, 1, 8},
2393 { 19200000, 1400000000, 875, 12, 1, 8},
2394 { 26000000, 1400000000, 700, 13, 1, 8},
2395
2396 /* 1.3 GHz */
2397 { 12000000, 1300000000, 975, 9, 1, 8},
2398 { 13000000, 1300000000, 1000, 10, 1, 8},
2399 { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */
2400 { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */
2401 { 26000000, 1300000000, 650, 13, 1, 8},
2402
2403 /* 1.2 GHz */
2404 { 12000000, 1200000000, 1000, 10, 1, 8},
2405 { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */
2406 { 16800000, 1200000000, 1000, 14, 1, 8},
2407 { 19200000, 1200000000, 1000, 16, 1, 8},
2408 { 26000000, 1200000000, 600, 13, 1, 8},
2409
2410 /* 1.1 GHz */
2411 { 12000000, 1100000000, 825, 9, 1, 8},
2412 { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */
2413 { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */
2414 { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */
2415 { 26000000, 1100000000, 550, 13, 1, 8},
2416
2417 /* 1 GHz */
2418 { 12000000, 1000000000, 1000, 12, 1, 8},
2419 { 13000000, 1000000000, 1000, 13, 1, 8},
2420 { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */
2421 { 19200000, 1000000000, 625, 12, 1, 8},
2422 { 26000000, 1000000000, 1000, 26, 1, 8},
2423
2424 { 0, 0, 0, 0, 0, 0 },
2425};
2426
2427static struct clk tegra_pll_x = {
2428 .name = "pll_x",
2429 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX,
2430 .ops = &tegra_pll_ops,
2431 .reg = 0xe0,
2432 .parent = &tegra_pll_ref,
2433 .max_rate = 1700000000,
2434 .u.pll = {
2435 .input_min = 2000000,
2436 .input_max = 31000000,
2437 .cf_min = 1000000,
2438 .cf_max = 6000000,
2439 .vco_min = 20000000,
2440 .vco_max = 1700000000,
2441 .freq_table = tegra_pll_x_freq_table,
2442 .lock_delay = 300,
2443 },
2444};
2445
2446static struct clk tegra_pll_x_out0 = {
2447 .name = "pll_x_out0",
2448 .ops = &tegra_pll_div_ops,
2449 .flags = DIV_2 | PLLX,
2450 .parent = &tegra_pll_x,
2451 .max_rate = 850000000,
2452};
2453
2454
2455static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
2456 /* PLLE special case: use cpcon field to store cml divider value */
2457 { 12000000, 100000000, 150, 1, 18, 11},
2458 { 216000000, 100000000, 200, 18, 24, 13},
2459 { 0, 0, 0, 0, 0, 0 },
2460};
2461
2462static struct clk tegra_pll_e = {
2463 .name = "pll_e",
2464 .flags = PLL_ALT_MISC_REG,
2465 .ops = &tegra_plle_ops,
2466 .reg = 0xe8,
2467 .max_rate = 100000000,
2468 .u.pll = {
2469 .input_min = 12000000,
2470 .input_max = 216000000,
2471 .cf_min = 12000000,
2472 .cf_max = 12000000,
2473 .vco_min = 1200000000,
2474 .vco_max = 2400000000U,
2475 .freq_table = tegra_pll_e_freq_table,
2476 .lock_delay = 300,
2477 .fixed_rate = 100000000,
2478 },
2479};
2480
2481static struct clk tegra_cml0_clk = {
2482 .name = "cml0",
2483 .parent = &tegra_pll_e,
2484 .ops = &tegra_cml_clk_ops,
2485 .reg = PLLE_AUX,
2486 .max_rate = 100000000,
2487 .u.periph = {
2488 .clk_num = 0,
2489 },
2490};
2491
2492static struct clk tegra_cml1_clk = {
2493 .name = "cml1",
2494 .parent = &tegra_pll_e,
2495 .ops = &tegra_cml_clk_ops,
2496 .reg = PLLE_AUX,
2497 .max_rate = 100000000,
2498 .u.periph = {
2499 .clk_num = 1,
2500 },
2501};
2502
2503static struct clk tegra_pciex_clk = {
2504 .name = "pciex",
2505 .parent = &tegra_pll_e,
2506 .ops = &tegra_pciex_clk_ops,
2507 .max_rate = 100000000,
2508 .u.periph = {
2509 .clk_num = 74,
2510 },
2511};
2512
2513/* Audio sync clocks */
2514#define SYNC_SOURCE(_id) \
2515 { \
2516 .name = #_id "_sync", \
2517 .rate = 24000000, \
2518 .max_rate = 24000000, \
2519 .ops = &tegra_sync_source_ops \
2520 }
2521static struct clk tegra_sync_source_list[] = {
2522 SYNC_SOURCE(spdif_in),
2523 SYNC_SOURCE(i2s0),
2524 SYNC_SOURCE(i2s1),
2525 SYNC_SOURCE(i2s2),
2526 SYNC_SOURCE(i2s3),
2527 SYNC_SOURCE(i2s4),
2528 SYNC_SOURCE(vimclk),
2529};
2530
2531static struct clk_mux_sel mux_audio_sync_clk[] = {
2532 { .input = &tegra_sync_source_list[0], .value = 0},
2533 { .input = &tegra_sync_source_list[1], .value = 1},
2534 { .input = &tegra_sync_source_list[2], .value = 2},
2535 { .input = &tegra_sync_source_list[3], .value = 3},
2536 { .input = &tegra_sync_source_list[4], .value = 4},
2537 { .input = &tegra_sync_source_list[5], .value = 5},
2538 { .input = &tegra_pll_a_out0, .value = 6},
2539 { .input = &tegra_sync_source_list[6], .value = 7},
2540 { 0, 0 }
2541};
2542
2543#define AUDIO_SYNC_CLK(_id, _index) \
2544 { \
2545 .name = #_id, \
2546 .inputs = mux_audio_sync_clk, \
2547 .reg = 0x4A0 + (_index) * 4, \
2548 .max_rate = 24000000, \
2549 .ops = &tegra_audio_sync_clk_ops \
2550 }
2551static struct clk tegra_clk_audio_list[] = {
2552 AUDIO_SYNC_CLK(audio0, 0),
2553 AUDIO_SYNC_CLK(audio1, 1),
2554 AUDIO_SYNC_CLK(audio2, 2),
2555 AUDIO_SYNC_CLK(audio3, 3),
2556 AUDIO_SYNC_CLK(audio4, 4),
2557 AUDIO_SYNC_CLK(audio, 5), /* SPDIF */
2558};
2559
2560#define AUDIO_SYNC_2X_CLK(_id, _index) \
2561 { \
2562 .name = #_id "_2x", \
2563 .flags = PERIPH_NO_RESET, \
2564 .max_rate = 48000000, \
2565 .ops = &tegra_clk_double_ops, \
2566 .reg = 0x49C, \
2567 .reg_shift = 24 + (_index), \
2568 .parent = &tegra_clk_audio_list[(_index)], \
2569 .u.periph = { \
2570 .clk_num = 113 + (_index), \
2571 }, \
2572 }
2573static struct clk tegra_clk_audio_2x_list[] = {
2574 AUDIO_SYNC_2X_CLK(audio0, 0),
2575 AUDIO_SYNC_2X_CLK(audio1, 1),
2576 AUDIO_SYNC_2X_CLK(audio2, 2),
2577 AUDIO_SYNC_2X_CLK(audio3, 3),
2578 AUDIO_SYNC_2X_CLK(audio4, 4),
2579 AUDIO_SYNC_2X_CLK(audio, 5), /* SPDIF */
2580};
2581
2582#define MUX_I2S_SPDIF(_id, _index) \
2583static struct clk_mux_sel mux_pllaout0_##_id##_2x_pllp_clkm[] = { \
2584 {.input = &tegra_pll_a_out0, .value = 0}, \
2585 {.input = &tegra_clk_audio_2x_list[(_index)], .value = 1}, \
2586 {.input = &tegra_pll_p, .value = 2}, \
2587 {.input = &tegra_clk_m, .value = 3}, \
2588 { 0, 0}, \
2589}
2590MUX_I2S_SPDIF(audio0, 0);
2591MUX_I2S_SPDIF(audio1, 1);
2592MUX_I2S_SPDIF(audio2, 2);
2593MUX_I2S_SPDIF(audio3, 3);
2594MUX_I2S_SPDIF(audio4, 4);
2595MUX_I2S_SPDIF(audio, 5); /* SPDIF */
2596
2597/* External clock outputs (through PMC) */
2598#define MUX_EXTERN_OUT(_id) \
2599static struct clk_mux_sel mux_clkm_clkm2_clkm4_extern##_id[] = { \
2600 {.input = &tegra_clk_m, .value = 0}, \
2601 {.input = &tegra_clk_m_div2, .value = 1}, \
2602 {.input = &tegra_clk_m_div4, .value = 2}, \
2603 {.input = NULL, .value = 3}, /* placeholder */ \
2604 { 0, 0}, \
2605}
2606MUX_EXTERN_OUT(1);
2607MUX_EXTERN_OUT(2);
2608MUX_EXTERN_OUT(3);
2609
2610static struct clk_mux_sel *mux_extern_out_list[] = {
2611 mux_clkm_clkm2_clkm4_extern1,
2612 mux_clkm_clkm2_clkm4_extern2,
2613 mux_clkm_clkm2_clkm4_extern3,
2614};
2615
2616#define CLK_OUT_CLK(_id) \
2617 { \
2618 .name = "clk_out_" #_id, \
2619 .lookup = { \
2620 .dev_id = "clk_out_" #_id, \
2621 .con_id = "extern" #_id, \
2622 }, \
2623 .ops = &tegra_clk_out_ops, \
2624 .reg = 0x1a8, \
2625 .inputs = mux_clkm_clkm2_clkm4_extern##_id, \
2626 .flags = MUX_CLK_OUT, \
2627 .max_rate = 216000000, \
2628 .u.periph = { \
2629 .clk_num = (_id - 1) * 8 + 2, \
2630 }, \
2631 }
2632static struct clk tegra_clk_out_list[] = {
2633 CLK_OUT_CLK(1),
2634 CLK_OUT_CLK(2),
2635 CLK_OUT_CLK(3),
2636};
2637
2638/* called after peripheral external clocks are initialized */
2639static void init_clk_out_mux(void)
2640{
2641 int i;
2642 struct clk *c;
2643
2644 /* output clock con_id is the name of peripheral
2645 external clock connected to input 3 of the output mux */
2646 for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) {
2647 c = tegra_get_clock_by_name(
2648 tegra_clk_out_list[i].lookup.con_id);
2649 if (!c)
2650 pr_err("%s: could not find clk %s\n", __func__,
2651 tegra_clk_out_list[i].lookup.con_id);
2652 mux_extern_out_list[i][3].input = c;
2653 }
2654}
2655
2656/* Peripheral muxes */
2657static struct clk_mux_sel mux_sclk[] = {
2658 { .input = &tegra_clk_m, .value = 0},
2659 { .input = &tegra_pll_c_out1, .value = 1},
2660 { .input = &tegra_pll_p_out4, .value = 2},
2661 { .input = &tegra_pll_p_out3, .value = 3},
2662 { .input = &tegra_pll_p_out2, .value = 4},
2663 /* { .input = &tegra_clk_d, .value = 5}, - no use on tegra30 */
2664 { .input = &tegra_clk_32k, .value = 6},
2665 { .input = &tegra_pll_m_out1, .value = 7},
2666 { 0, 0},
2667};
2668
2669static struct clk tegra_clk_sclk = {
2670 .name = "sclk",
2671 .inputs = mux_sclk,
2672 .reg = 0x28,
2673 .ops = &tegra_super_ops,
2674 .max_rate = 334000000,
2675 .min_rate = 40000000,
2676};
2677
2678static struct clk tegra_clk_blink = {
2679 .name = "blink",
2680 .parent = &tegra_clk_32k,
2681 .reg = 0x40,
2682 .ops = &tegra_blink_clk_ops,
2683 .max_rate = 32768,
2684};
2685
2686static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
2687 { .input = &tegra_pll_m, .value = 0},
2688 { .input = &tegra_pll_c, .value = 1},
2689 { .input = &tegra_pll_p, .value = 2},
2690 { .input = &tegra_pll_a_out0, .value = 3},
2691 { 0, 0},
2692};
2693
2694static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
2695 { .input = &tegra_pll_p, .value = 0},
2696 { .input = &tegra_pll_c, .value = 1},
2697 { .input = &tegra_pll_m, .value = 2},
2698 { .input = &tegra_clk_m, .value = 3},
2699 { 0, 0},
2700};
2701
2702static struct clk_mux_sel mux_pllp_clkm[] = {
2703 { .input = &tegra_pll_p, .value = 0},
2704 { .input = &tegra_clk_m, .value = 3},
2705 { 0, 0},
2706};
2707
2708static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
2709 {.input = &tegra_pll_p, .value = 0},
2710 {.input = &tegra_pll_d_out0, .value = 1},
2711 {.input = &tegra_pll_c, .value = 2},
2712 {.input = &tegra_clk_m, .value = 3},
2713 { 0, 0},
2714};
2715
2716static struct clk_mux_sel mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
2717 {.input = &tegra_pll_p, .value = 0},
2718 {.input = &tegra_pll_m, .value = 1},
2719 {.input = &tegra_pll_d_out0, .value = 2},
2720 {.input = &tegra_pll_a_out0, .value = 3},
2721 {.input = &tegra_pll_c, .value = 4},
2722 {.input = &tegra_pll_d2_out0, .value = 5},
2723 {.input = &tegra_clk_m, .value = 6},
2724 { 0, 0},
2725};
2726
2727static struct clk_mux_sel mux_plla_pllc_pllp_clkm[] = {
2728 { .input = &tegra_pll_a_out0, .value = 0},
2729 /* { .input = &tegra_pll_c, .value = 1}, no use on tegra30 */
2730 { .input = &tegra_pll_p, .value = 2},
2731 { .input = &tegra_clk_m, .value = 3},
2732 { 0, 0},
2733};
2734
2735static struct clk_mux_sel mux_pllp_pllc_clk32_clkm[] = {
2736 {.input = &tegra_pll_p, .value = 0},
2737 {.input = &tegra_pll_c, .value = 1},
2738 {.input = &tegra_clk_32k, .value = 2},
2739 {.input = &tegra_clk_m, .value = 3},
2740 { 0, 0},
2741};
2742
2743static struct clk_mux_sel mux_pllp_pllc_clkm_clk32[] = {
2744 {.input = &tegra_pll_p, .value = 0},
2745 {.input = &tegra_pll_c, .value = 1},
2746 {.input = &tegra_clk_m, .value = 2},
2747 {.input = &tegra_clk_32k, .value = 3},
2748 { 0, 0},
2749};
2750
2751static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
2752 {.input = &tegra_pll_p, .value = 0},
2753 {.input = &tegra_pll_c, .value = 1},
2754 {.input = &tegra_pll_m, .value = 2},
2755 { 0, 0},
2756};
2757
2758static struct clk_mux_sel mux_clk_m[] = {
2759 { .input = &tegra_clk_m, .value = 0},
2760 { 0, 0},
2761};
2762
2763static struct clk_mux_sel mux_pllp_out3[] = {
2764 { .input = &tegra_pll_p_out3, .value = 0},
2765 { 0, 0},
2766};
2767
2768static struct clk_mux_sel mux_plld_out0[] = {
2769 { .input = &tegra_pll_d_out0, .value = 0},
2770 { 0, 0},
2771};
2772
2773static struct clk_mux_sel mux_plld_out0_plld2_out0[] = {
2774 { .input = &tegra_pll_d_out0, .value = 0},
2775 { .input = &tegra_pll_d2_out0, .value = 1},
2776 { 0, 0},
2777};
2778
2779static struct clk_mux_sel mux_clk_32k[] = {
2780 { .input = &tegra_clk_32k, .value = 0},
2781 { 0, 0},
2782};
2783
2784static struct clk_mux_sel mux_plla_clk32_pllp_clkm_plle[] = {
2785 { .input = &tegra_pll_a_out0, .value = 0},
2786 { .input = &tegra_clk_32k, .value = 1},
2787 { .input = &tegra_pll_p, .value = 2},
2788 { .input = &tegra_clk_m, .value = 3},
2789 { .input = &tegra_pll_e, .value = 4},
2790 { 0, 0},
2791};
2792
2793static struct clk_mux_sel mux_cclk_g[] = {
2794 { .input = &tegra_clk_m, .value = 0},
2795 { .input = &tegra_pll_c, .value = 1},
2796 { .input = &tegra_clk_32k, .value = 2},
2797 { .input = &tegra_pll_m, .value = 3},
2798 { .input = &tegra_pll_p, .value = 4},
2799 { .input = &tegra_pll_p_out4, .value = 5},
2800 { .input = &tegra_pll_p_out3, .value = 6},
2801 { .input = &tegra_pll_x, .value = 8},
2802 { 0, 0},
2803};
2804
2805static struct clk tegra_clk_cclk_g = {
2806 .name = "cclk_g",
2807 .flags = DIV_U71 | DIV_U71_INT,
2808 .inputs = mux_cclk_g,
2809 .reg = 0x368,
2810 .ops = &tegra_super_ops,
2811 .max_rate = 1700000000,
2812};
2813
2814static struct clk tegra30_clk_twd = {
2815 .parent = &tegra_clk_cclk_g,
2816 .name = "twd",
2817 .ops = &tegra30_twd_ops,
2818 .max_rate = 1400000000, /* Same as tegra_clk_cpu_cmplx.max_rate */
2819 .mul = 1,
2820 .div = 2,
2821};
2822
2823#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
2824 { \
2825 .name = _name, \
2826 .lookup = { \
2827 .dev_id = _dev, \
2828 .con_id = _con, \
2829 }, \
2830 .ops = &tegra_periph_clk_ops, \
2831 .reg = _reg, \
2832 .inputs = _inputs, \
2833 .flags = _flags, \
2834 .max_rate = _max, \
2835 .u.periph = { \
2836 .clk_num = _clk_num, \
2837 }, \
2838 }
2839
2840#define PERIPH_CLK_EX(_name, _dev, _con, _clk_num, _reg, _max, _inputs, \
2841 _flags, _ops) \
2842 { \
2843 .name = _name, \
2844 .lookup = { \
2845 .dev_id = _dev, \
2846 .con_id = _con, \
2847 }, \
2848 .ops = _ops, \
2849 .reg = _reg, \
2850 .inputs = _inputs, \
2851 .flags = _flags, \
2852 .max_rate = _max, \
2853 .u.periph = { \
2854 .clk_num = _clk_num, \
2855 }, \
2856 }
2857
2858#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\
2859 { \
2860 .name = _name, \
2861 .lookup = { \
2862 .dev_id = _dev, \
2863 .con_id = _con, \
2864 }, \
2865 .ops = &tegra_clk_shared_bus_ops, \
2866 .parent = _parent, \
2867 .u.shared_bus_user = { \
2868 .client_id = _id, \
2869 .client_div = _div, \
2870 .mode = _mode, \
2871 }, \
2872 }
2873struct clk tegra_list_clks[] = {
2874 PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 26000000, mux_clk_m, 0),
2875 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB),
2876 PERIPH_CLK("kbc", "tegra-kbc", NULL, 36, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB),
2877 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
2878 PERIPH_CLK("kfuse", "kfuse-tegra", NULL, 40, 0, 26000000, mux_clk_m, 0),
2879 PERIPH_CLK("fuse", "fuse-tegra", "fuse", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB),
2880 PERIPH_CLK("fuse_burn", "fuse-tegra", "fuse_burn", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB),
2881 PERIPH_CLK("apbif", "tegra30-ahub", "apbif", 107, 0, 26000000, mux_clk_m, 0),
2882 PERIPH_CLK("i2s0", "tegra30-i2s.0", NULL, 30, 0x1d8, 26000000, mux_pllaout0_audio0_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2883 PERIPH_CLK("i2s1", "tegra30-i2s.1", NULL, 11, 0x100, 26000000, mux_pllaout0_audio1_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2884 PERIPH_CLK("i2s2", "tegra30-i2s.2", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2885 PERIPH_CLK("i2s3", "tegra30-i2s.3", NULL, 101, 0x3bc, 26000000, mux_pllaout0_audio3_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2886 PERIPH_CLK("i2s4", "tegra30-i2s.4", NULL, 102, 0x3c0, 26000000, mux_pllaout0_audio4_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2887 PERIPH_CLK("spdif_out", "tegra30-spdif", "spdif_out", 10, 0x108, 100000000, mux_pllaout0_audio_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2888 PERIPH_CLK("spdif_in", "tegra30-spdif", "spdif_in", 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71 | PERIPH_ON_APB),
2889 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_clk32_clkm, MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
2890 PERIPH_CLK("d_audio", "tegra30-ahub", "d_audio", 106, 0x3d0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
2891 PERIPH_CLK("dam0", "tegra30-dam.0", NULL, 108, 0x3d8, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
2892 PERIPH_CLK("dam1", "tegra30-dam.1", NULL, 109, 0x3dc, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
2893 PERIPH_CLK("dam2", "tegra30-dam.2", NULL, 110, 0x3e0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71),
2894 PERIPH_CLK("hda", "tegra30-hda", "hda", 125, 0x428, 108000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2895 PERIPH_CLK("hda2codec_2x", "tegra30-hda", "hda2codec", 111, 0x3e4, 48000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2896 PERIPH_CLK("hda2hdmi", "tegra30-hda", "hda2hdmi", 128, 0, 48000000, mux_clk_m, 0),
2897 PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2898 PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2899 PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2900 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2901 PERIPH_CLK("sbc5", "spi_tegra.4", NULL, 104, 0x3c8, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2902 PERIPH_CLK("sbc6", "spi_tegra.5", NULL, 105, 0x3cc, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2903 PERIPH_CLK("sata_oob", "tegra_sata_oob", NULL, 123, 0x420, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2904 PERIPH_CLK("sata", "tegra_sata", NULL, 124, 0x424, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2905 PERIPH_CLK("sata_cold", "tegra_sata_cold", NULL, 129, 0, 48000000, mux_clk_m, 0),
2906 PERIPH_CLK_EX("ndflash", "tegra_nand", NULL, 13, 0x160, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71, &tegra_nand_clk_ops),
2907 PERIPH_CLK("ndspeed", "tegra_nand_speed", NULL, 80, 0x3f8, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2908 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2909 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2910 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2911 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2912 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
2913 PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0),
2914 PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0),
2915 PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0),
2916 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT),
2917 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
2918 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
2919 PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2920 PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 127000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
2921 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */
2922 PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2923 PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2924 PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2925 PERIPH_CLK("i2c4", "tegra-i2c.3", NULL, 103, 0x3c4, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2926 PERIPH_CLK("i2c5", "tegra-i2c.4", NULL, 47, 0x128, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB),
2927 PERIPH_CLK("uarta", "tegra_uart.0", NULL, 6, 0x178, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2928 PERIPH_CLK("uartb", "tegra_uart.1", NULL, 7, 0x17c, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2929 PERIPH_CLK("uartc", "tegra_uart.2", NULL, 55, 0x1a0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2930 PERIPH_CLK("uartd", "tegra_uart.3", NULL, 65, 0x1c0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2931 PERIPH_CLK("uarte", "tegra_uart.4", NULL, 66, 0x1c4, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2932 PERIPH_CLK("uarta_dbg", "serial8250.0", "uarta", 6, 0x178, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2933 PERIPH_CLK("uartb_dbg", "serial8250.0", "uartb", 7, 0x17c, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2934 PERIPH_CLK("uartc_dbg", "serial8250.0", "uartc", 55, 0x1a0, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2935 PERIPH_CLK("uartd_dbg", "serial8250.0", "uartd", 65, 0x1c0, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2936 PERIPH_CLK("uarte_dbg", "serial8250.0", "uarte", 66, 0x1c4, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
2937 PERIPH_CLK_EX("vi", "tegra_camera", "vi", 20, 0x148, 425000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT, &tegra_vi_clk_ops),
2938 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
2939 PERIPH_CLK("3d2", "3d2", NULL, 98, 0x3b0, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
2940 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE),
2941 PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET),
2942 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
2943 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
2944 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 260000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
2945 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2946 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2947 PERIPH_CLK_EX("dtv", "dtv", NULL, 79, 0x1dc, 250000000, mux_clk_m, 0, &tegra_dtv_clk_ops),
2948 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8 | DIV_U71),
2949 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 220000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
2950 PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8),
2951 PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8),
2952 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2953 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2954 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2955 PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0),
2956 PERIPH_CLK_EX("dsib", "tegradc.1", "dsib", 82, 0xd0, 500000000, mux_plld_out0_plld2_out0, MUX | PLLD, &tegra_dsib_clk_ops),
2957 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0),
2958 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
2959 PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
2960
2961 PERIPH_CLK("tsensor", "tegra-tsensor", NULL, 100, 0x3b8, 216000000, mux_pllp_pllc_clkm_clk32, MUX | DIV_U71),
2962 PERIPH_CLK("actmon", "actmon", NULL, 119, 0x3e8, 216000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71),
2963 PERIPH_CLK("extern1", "extern1", NULL, 120, 0x3ec, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71),
2964 PERIPH_CLK("extern2", "extern2", NULL, 121, 0x3f0, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71),
2965 PERIPH_CLK("extern3", "extern3", NULL, 122, 0x3f4, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71),
2966 PERIPH_CLK("i2cslow", "i2cslow", NULL, 81, 0x3fc, 26000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
2967 PERIPH_CLK("pcie", "tegra-pcie", "pcie", 70, 0, 250000000, mux_clk_m, 0),
2968 PERIPH_CLK("afi", "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0),
2969 PERIPH_CLK("se", "se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT),
2970};
2971
2972#define CLK_DUPLICATE(_name, _dev, _con) \
2973 { \
2974 .name = _name, \
2975 .lookup = { \
2976 .dev_id = _dev, \
2977 .con_id = _con, \
2978 }, \
2979 }
2980
2981/* Some clocks may be used by different drivers depending on the board
2982 * configuration. List those here to register them twice in the clock lookup
2983 * table under two names.
2984 */
2985struct clk_duplicate tegra_clk_duplicates[] = {
2986 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
2987 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
2988 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
2989 CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
2990 CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
2991 CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
2992 CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
2993 CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
2994 CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
2995 CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
2996 CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
2997 CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
2998 CLK_DUPLICATE("bsev", "nvavp", "bsev"),
2999 CLK_DUPLICATE("vde", "tegra-aes", "vde"),
3000 CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
3001 CLK_DUPLICATE("bsea", "nvavp", "bsea"),
3002 CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
3003 CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
3004 CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
3005 CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
3006 CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
3007 CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
3008 CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
3009 CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
3010 CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
3011 CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
3012 CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
3013 CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
3014 CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
3015 CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
3016 CLK_DUPLICATE("twd", "smp_twd", NULL),
3017 CLK_DUPLICATE("vcp", "nvavp", "vcp"),
3018};
3019
3020struct clk *tegra_ptr_clks[] = {
3021 &tegra_clk_32k,
3022 &tegra_clk_m,
3023 &tegra_clk_m_div2,
3024 &tegra_clk_m_div4,
3025 &tegra_pll_ref,
3026 &tegra_pll_m,
3027 &tegra_pll_m_out1,
3028 &tegra_pll_c,
3029 &tegra_pll_c_out1,
3030 &tegra_pll_p,
3031 &tegra_pll_p_out1,
3032 &tegra_pll_p_out2,
3033 &tegra_pll_p_out3,
3034 &tegra_pll_p_out4,
3035 &tegra_pll_a,
3036 &tegra_pll_a_out0,
3037 &tegra_pll_d,
3038 &tegra_pll_d_out0,
3039 &tegra_pll_d2,
3040 &tegra_pll_d2_out0,
3041 &tegra_pll_u,
3042 &tegra_pll_x,
3043 &tegra_pll_x_out0,
3044 &tegra_pll_e,
3045 &tegra_clk_cclk_g,
3046 &tegra_cml0_clk,
3047 &tegra_cml1_clk,
3048 &tegra_pciex_clk,
3049 &tegra_clk_sclk,
3050 &tegra_clk_blink,
3051 &tegra30_clk_twd,
3052};
3053
3054
3055static void tegra30_init_one_clock(struct clk *c)
3056{
3057 clk_init(c);
3058 INIT_LIST_HEAD(&c->shared_bus_list);
3059 if (!c->lookup.dev_id && !c->lookup.con_id)
3060 c->lookup.con_id = c->name;
3061 c->lookup.clk = c;
3062 clkdev_add(&c->lookup);
3063}
3064
3065void __init tegra30_init_clocks(void)
3066{
3067 int i;
3068 struct clk *c;
3069
3070 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
3071 tegra30_init_one_clock(tegra_ptr_clks[i]);
3072
3073 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
3074 tegra30_init_one_clock(&tegra_list_clks[i]);
3075
3076 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
3077 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
3078 if (!c) {
3079 pr_err("%s: Unknown duplicate clock %s\n", __func__,
3080 tegra_clk_duplicates[i].name);
3081 continue;
3082 }
3083
3084 tegra_clk_duplicates[i].lookup.clk = c;
3085 clkdev_add(&tegra_clk_duplicates[i].lookup);
3086 }
3087
3088 for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
3089 tegra30_init_one_clock(&tegra_sync_source_list[i]);
3090 for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
3091 tegra30_init_one_clock(&tegra_clk_audio_list[i]);
3092 for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
3093 tegra30_init_one_clock(&tegra_clk_audio_2x_list[i]);
3094
3095 init_clk_out_mux();
3096 for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
3097 tegra30_init_one_clock(&tegra_clk_out_list[i]);
3098
3099}
diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
index f5b7e0fa237..220dd6f9312 100644
--- a/arch/arm/plat-mxc/cpu.c
+++ b/arch/arm/plat-mxc/cpu.c
@@ -1,5 +1,6 @@
1 1
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/io.h>
3#include <mach/hardware.h> 4#include <mach/hardware.h>
4 5
5unsigned int __mxc_cpu_type; 6unsigned int __mxc_cpu_type;
@@ -18,3 +19,26 @@ void imx_print_silicon_rev(const char *cpu, int srev)
18 pr_info("CPU identified as %s, silicon rev %d.%d\n", 19 pr_info("CPU identified as %s, silicon rev %d.%d\n",
19 cpu, (srev >> 4) & 0xf, srev & 0xf); 20 cpu, (srev >> 4) & 0xf, srev & 0xf);
20} 21}
22
23void __init imx_set_aips(void __iomem *base)
24{
25 unsigned int reg;
26/*
27 * Set all MPROTx to be non-bufferable, trusted for R/W,
28 * not forced to user-mode.
29 */
30 __raw_writel(0x77777777, base + 0x0);
31 __raw_writel(0x77777777, base + 0x4);
32
33/*
34 * Set all OPACRx to be non-bufferable, to not require
35 * supervisor privilege level for access, allow for
36 * write access and untrusted master access.
37 */
38 __raw_writel(0x0, base + 0x40);
39 __raw_writel(0x0, base + 0x44);
40 __raw_writel(0x0, base + 0x48);
41 __raw_writel(0x0, base + 0x4C);
42 reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
43 __raw_writel(reg, base + 0x50);
44}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 1bf0df81bdc..7c24e5ab7d5 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -75,6 +75,7 @@ extern void mxc_restart(char, const char *);
75extern void mxc_arch_reset_init(void __iomem *); 75extern void mxc_arch_reset_init(void __iomem *);
76extern int mx53_revision(void); 76extern int mx53_revision(void);
77extern int mx53_display_revision(void); 77extern int mx53_display_revision(void);
78extern void imx_set_aips(void __iomem *);
78 79
79enum mxc_cpu_pwr_mode { 80enum mxc_cpu_pwr_mode {
80 WAIT_CLOCKED, /* wfi only */ 81 WAIT_CLOCKED, /* wfi only */
@@ -84,6 +85,14 @@ enum mxc_cpu_pwr_mode {
84 STOP_POWER_OFF, /* STOP + SRPG */ 85 STOP_POWER_OFF, /* STOP + SRPG */
85}; 86};
86 87
88enum mx3_cpu_pwr_mode {
89 MX3_RUN,
90 MX3_WAIT,
91 MX3_DOZE,
92 MX3_SLEEP,
93};
94
95extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
87extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode); 96extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
88extern void imx_print_silicon_rev(const char *cpu, int srev); 97extern void imx_print_silicon_rev(const char *cpu, int srev);
89 98
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 4f18eaed451..dc6a86bf217 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -449,7 +449,12 @@ IS_OMAP_TYPE(3517, 0x3517)
449#define OMAP447X_CLASS 0x44700044 449#define OMAP447X_CLASS 0x44700044
450#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) 450#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8))
451 451
452void omap2_check_revision(void); 452void omap2xxx_check_revision(void);
453void omap3xxx_check_revision(void);
454void omap4xxx_check_revision(void);
455void omap3xxx_check_features(void);
456void ti81xx_check_features(void);
457void omap4xxx_check_features(void);
453 458
454/* 459/*
455 * Runtime detection of OMAP3 features 460 * Runtime detection of OMAP3 features
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 8167ce66188..7a308699f81 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -80,6 +80,16 @@ config S5P_DEV_FIMC3
80 help 80 help
81 Compile in platform device definitions for FIMC controller 3 81 Compile in platform device definitions for FIMC controller 3
82 82
83config S5P_DEV_JPEG
84 bool
85 help
86 Compile in platform device definitions for JPEG codec
87
88config S5P_DEV_G2D
89 bool
90 help
91 Compile in platform device definitions for G2D device
92
83config S5P_DEV_FIMD0 93config S5P_DEV_FIMD0
84 bool 94 bool
85 help 95 help
diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S
index 0fd591bfc9f..006bd01eda0 100644
--- a/arch/arm/plat-s5p/sleep.S
+++ b/arch/arm/plat-s5p/sleep.S
@@ -23,9 +23,18 @@
23*/ 23*/
24 24
25#include <linux/linkage.h> 25#include <linux/linkage.h>
26#include <asm/assembler.h> 26#include <asm/asm-offsets.h>
27#include <asm/hardware/cache-l2x0.h>
27 28
28 .text 29/*
30 * The following code is located into the .data section. This is to
31 * allow l2x0_regs_phys to be accessed with a relative load while we
32 * can't rely on any MMU translation. We could have put l2x0_regs_phys
33 * in the .text section as well, but some setups might insist on it to
34 * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
35 */
36 .data
37 .align
29 38
30 /* 39 /*
31 * sleep magic, to allow the bootloader to check for an valid 40 * sleep magic, to allow the bootloader to check for an valid
@@ -39,11 +48,34 @@
39 * s3c_cpu_resume 48 * s3c_cpu_resume
40 * 49 *
41 * resume code entry for bootloader to call 50 * resume code entry for bootloader to call
42 *
43 * we must put this code here in the data segment as we have no
44 * other way of restoring the stack pointer after sleep, and we
45 * must not write to the code segment (code is read-only)
46 */ 51 */
47 52
48ENTRY(s3c_cpu_resume) 53ENTRY(s3c_cpu_resume)
54#ifdef CONFIG_CACHE_L2X0
55 adr r0, l2x0_regs_phys
56 ldr r0, [r0]
57 ldr r1, [r0, #L2X0_R_PHY_BASE]
58 ldr r2, [r1, #L2X0_CTRL]
59 tst r2, #0x1
60 bne resume_l2on
61 ldr r2, [r0, #L2X0_R_AUX_CTRL]
62 str r2, [r1, #L2X0_AUX_CTRL]
63 ldr r2, [r0, #L2X0_R_TAG_LATENCY]
64 str r2, [r1, #L2X0_TAG_LATENCY_CTRL]
65 ldr r2, [r0, #L2X0_R_DATA_LATENCY]
66 str r2, [r1, #L2X0_DATA_LATENCY_CTRL]
67 ldr r2, [r0, #L2X0_R_PREFETCH_CTRL]
68 str r2, [r1, #L2X0_PREFETCH_CTRL]
69 ldr r2, [r0, #L2X0_R_PWR_CTRL]
70 str r2, [r1, #L2X0_POWER_CTRL]
71 mov r2, #1
72 str r2, [r1, #L2X0_CTRL]
73resume_l2on:
74#endif
49 b cpu_resume 75 b cpu_resume
76ENDPROC(s3c_cpu_resume)
77#ifdef CONFIG_CACHE_L2X0
78 .globl l2x0_regs_phys
79l2x0_regs_phys:
80 .long 0
81#endif
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 10f71179071..65c5eca475e 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable)
84 84
85int clk_enable(struct clk *clk) 85int clk_enable(struct clk *clk)
86{ 86{
87 unsigned long flags;
88
87 if (IS_ERR(clk) || clk == NULL) 89 if (IS_ERR(clk) || clk == NULL)
88 return -EINVAL; 90 return -EINVAL;
89 91
90 clk_enable(clk->parent); 92 clk_enable(clk->parent);
91 93
92 spin_lock(&clocks_lock); 94 spin_lock_irqsave(&clocks_lock, flags);
93 95
94 if ((clk->usage++) == 0) 96 if ((clk->usage++) == 0)
95 (clk->enable)(clk, 1); 97 (clk->enable)(clk, 1);
96 98
97 spin_unlock(&clocks_lock); 99 spin_unlock_irqrestore(&clocks_lock, flags);
98 return 0; 100 return 0;
99} 101}
100 102
101void clk_disable(struct clk *clk) 103void clk_disable(struct clk *clk)
102{ 104{
105 unsigned long flags;
106
103 if (IS_ERR(clk) || clk == NULL) 107 if (IS_ERR(clk) || clk == NULL)
104 return; 108 return;
105 109
106 spin_lock(&clocks_lock); 110 spin_lock_irqsave(&clocks_lock, flags);
107 111
108 if ((--clk->usage) == 0) 112 if ((--clk->usage) == 0)
109 (clk->enable)(clk, 0); 113 (clk->enable)(clk, 0);
110 114
111 spin_unlock(&clocks_lock); 115 spin_unlock_irqrestore(&clocks_lock, flags);
112 clk_disable(clk->parent); 116 clk_disable(clk->parent);
113} 117}
114 118
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index a976c023b28..5f197dcaf10 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -77,7 +77,7 @@ static struct platform_device samsung_dfl_bl_device __initdata = {
77 * @gpio_info: structure containing GPIO info for PWM timer 77 * @gpio_info: structure containing GPIO info for PWM timer
78 * @bl_data: structure containing Backlight control data 78 * @bl_data: structure containing Backlight control data
79 */ 79 */
80void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, 80void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
81 struct platform_pwm_backlight_data *bl_data) 81 struct platform_pwm_backlight_data *bl_data)
82{ 82{
83 int ret = 0; 83 int ret = 0;
@@ -115,6 +115,8 @@ void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
115 samsung_bl_data->init = bl_data->init; 115 samsung_bl_data->init = bl_data->init;
116 if (bl_data->notify) 116 if (bl_data->notify)
117 samsung_bl_data->notify = bl_data->notify; 117 samsung_bl_data->notify = bl_data->notify;
118 if (bl_data->notify_after)
119 samsung_bl_data->notify_after = bl_data->notify_after;
118 if (bl_data->exit) 120 if (bl_data->exit)
119 samsung_bl_data->exit = bl_data->exit; 121 samsung_bl_data->exit = bl_data->exit;
120 if (bl_data->check_fb) 122 if (bl_data->check_fb)
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index d322ba883f2..8b928f9bc1c 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -57,6 +57,7 @@
57#include <plat/sdhci.h> 57#include <plat/sdhci.h>
58#include <plat/ts.h> 58#include <plat/ts.h>
59#include <plat/udc.h> 59#include <plat/udc.h>
60#include <plat/udc-hs.h>
60#include <plat/usb-control.h> 61#include <plat/usb-control.h>
61#include <plat/usb-phy.h> 62#include <plat/usb-phy.h>
62#include <plat/regs-iic.h> 63#include <plat/regs-iic.h>
@@ -267,6 +268,52 @@ struct platform_device s5p_device_fimc3 = {
267}; 268};
268#endif /* CONFIG_S5P_DEV_FIMC3 */ 269#endif /* CONFIG_S5P_DEV_FIMC3 */
269 270
271/* G2D */
272
273#ifdef CONFIG_S5P_DEV_G2D
274static struct resource s5p_g2d_resource[] = {
275 [0] = {
276 .start = S5P_PA_G2D,
277 .end = S5P_PA_G2D + SZ_4K - 1,
278 .flags = IORESOURCE_MEM,
279 },
280 [1] = {
281 .start = IRQ_2D,
282 .end = IRQ_2D,
283 .flags = IORESOURCE_IRQ,
284 },
285};
286
287struct platform_device s5p_device_g2d = {
288 .name = "s5p-g2d",
289 .id = 0,
290 .num_resources = ARRAY_SIZE(s5p_g2d_resource),
291 .resource = s5p_g2d_resource,
292 .dev = {
293 .dma_mask = &samsung_device_dma_mask,
294 .coherent_dma_mask = DMA_BIT_MASK(32),
295 },
296};
297#endif /* CONFIG_S5P_DEV_G2D */
298
299#ifdef CONFIG_S5P_DEV_JPEG
300static struct resource s5p_jpeg_resource[] = {
301 [0] = DEFINE_RES_MEM(S5P_PA_JPEG, SZ_4K),
302 [1] = DEFINE_RES_IRQ(IRQ_JPEG),
303};
304
305struct platform_device s5p_device_jpeg = {
306 .name = "s5p-jpeg",
307 .id = 0,
308 .num_resources = ARRAY_SIZE(s5p_jpeg_resource),
309 .resource = s5p_jpeg_resource,
310 .dev = {
311 .dma_mask = &samsung_device_dma_mask,
312 .coherent_dma_mask = DMA_BIT_MASK(32),
313 },
314};
315#endif /* CONFIG_S5P_DEV_JPEG */
316
270/* FIMD0 */ 317/* FIMD0 */
271 318
272#ifdef CONFIG_S5P_DEV_FIMD0 319#ifdef CONFIG_S5P_DEV_FIMD0
@@ -758,7 +805,7 @@ struct platform_device s3c_device_cfcon = {
758 .resource = s3c_cfcon_resource, 805 .resource = s3c_cfcon_resource,
759}; 806};
760 807
761void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) 808void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
762{ 809{
763 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), 810 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
764 &s3c_device_cfcon); 811 &s3c_device_cfcon);
@@ -876,7 +923,7 @@ struct platform_device s5p_device_mfc_r = {
876 923
877#ifdef CONFIG_S5P_DEV_CSIS0 924#ifdef CONFIG_S5P_DEV_CSIS0
878static struct resource s5p_mipi_csis0_resource[] = { 925static struct resource s5p_mipi_csis0_resource[] = {
879 [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K), 926 [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_16K),
880 [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0), 927 [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0),
881}; 928};
882 929
@@ -890,7 +937,7 @@ struct platform_device s5p_device_mipi_csis0 = {
890 937
891#ifdef CONFIG_S5P_DEV_CSIS1 938#ifdef CONFIG_S5P_DEV_CSIS1
892static struct resource s5p_mipi_csis1_resource[] = { 939static struct resource s5p_mipi_csis1_resource[] = {
893 [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K), 940 [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_16K),
894 [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1), 941 [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1),
895}; 942};
896 943
@@ -1038,7 +1085,7 @@ struct platform_device s3c64xx_device_onenand1 = {
1038 .resource = s3c64xx_onenand1_resources, 1085 .resource = s3c64xx_onenand1_resources,
1039}; 1086};
1040 1087
1041void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) 1088void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
1042{ 1089{
1043 s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), 1090 s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
1044 &s3c64xx_device_onenand1); 1091 &s3c64xx_device_onenand1);
@@ -1412,6 +1459,19 @@ struct platform_device s3c_device_usb_hsotg = {
1412 .coherent_dma_mask = DMA_BIT_MASK(32), 1459 .coherent_dma_mask = DMA_BIT_MASK(32),
1413 }, 1460 },
1414}; 1461};
1462
1463void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
1464{
1465 struct s3c_hsotg_plat *npd;
1466
1467 npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
1468 &s3c_device_usb_hsotg);
1469
1470 if (!npd->phy_init)
1471 npd->phy_init = s5p_usb_phy_init;
1472 if (!npd->phy_exit)
1473 npd->phy_exit = s5p_usb_phy_exit;
1474}
1415#endif /* CONFIG_S3C_DEV_USB_HSOTG */ 1475#endif /* CONFIG_S3C_DEV_USB_HSOTG */
1416 1476
1417/* USB High Spped 2.0 Device (Gadget) */ 1477/* USB High Spped 2.0 Device (Gadget) */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4214ea0ff8f..5e7972de3ed 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -79,6 +79,8 @@ extern struct platform_device s5p_device_fimc1;
79extern struct platform_device s5p_device_fimc2; 79extern struct platform_device s5p_device_fimc2;
80extern struct platform_device s5p_device_fimc3; 80extern struct platform_device s5p_device_fimc3;
81extern struct platform_device s5p_device_fimc_md; 81extern struct platform_device s5p_device_fimc_md;
82extern struct platform_device s5p_device_jpeg;
83extern struct platform_device s5p_device_g2d;
82extern struct platform_device s5p_device_fimd0; 84extern struct platform_device s5p_device_fimd0;
83extern struct platform_device s5p_device_hdmi; 85extern struct platform_device s5p_device_hdmi;
84extern struct platform_device s5p_device_i2c_hdmiphy; 86extern struct platform_device s5p_device_i2c_hdmiphy;
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
index a111ad87183..fcf27966206 100644
--- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
@@ -25,8 +25,9 @@
25#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) 25#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
26 26
27#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) 27#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00)
28#define SRC_PHYPWR_OTG_DISABLE (1 << 4) 28#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
29#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3) 29#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
30#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
30#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) 31#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1)
31 32
32#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) 33#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04)
@@ -42,7 +43,7 @@
42 43
43#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) 44#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08)
44#define S3C_RSTCON_PHYCLK (1 << 2) 45#define S3C_RSTCON_PHYCLK (1 << 2)
45#define S3C_RSTCON_HCLK (1 << 2) 46#define S3C_RSTCON_HCLK (1 << 1)
46#define S3C_RSTCON_PHY (1 << 0) 47#define S3C_RSTCON_PHY (1 << 0)
47 48
48#define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) 49#define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20)
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
index a22a4f2eea9..c9e3667cb2b 100644
--- a/arch/arm/plat-samsung/include/plat/udc-hs.h
+++ b/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -26,4 +26,9 @@ enum s3c_hsotg_dmamode {
26struct s3c_hsotg_plat { 26struct s3c_hsotg_plat {
27 enum s3c_hsotg_dmamode dma; 27 enum s3c_hsotg_dmamode dma;
28 unsigned int is_osc : 1; 28 unsigned int is_osc : 1;
29
30 int (*phy_init)(struct platform_device *pdev, int type);
31 int (*phy_exit)(struct platform_device *pdev, int type);
29}; 32};
33
34extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd);