提交 304ea747 编写于 作者: A Arnd Bergmann

Merge branch 'imx/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6.git into next/dt2

Shawn Guo <shawn.guo@linaro.org> writes:

  I chose to base it on Sascha's imx-common-clk series than -rc, because
  otherwise it will keep patching clock file that has been removed by
  imx-common-clk series.  It also depends on imx-pinctrl pull-request
  I just sent to be functional.

  Note: when imx-common-clk and imx-pinctrl get merged together, the
  following files will have conflicts.  But the conflicts should not be
  so hard to resolve.

[arnd: resolved those merge conflicts by pulling pinctrl branch]

* imx/dt: (24 commits)
  ARM: dts: imx53-qsb: enable audio support
  ARM: dts: imx51-babbage: enable audio support
  ARM: imx: add audio codec clk lookup for imx53-qsb
  ARM: imx: add audmux pad setting for imx51-babbage
  ARM: imx: add more imx5 ssi clocks
  ARM: dts: imx53-qsb: Add Dialog DA9053 PMIC support
  ARM: dts: imx6q-sabrelite: add serial2 pinctrl support
  ARM: dts: imx6q-sabrelite: add sound device imx6q-sabrelite-sgtl5000
  ARM: imx6q_sabrelite: clk_register_clkdev cko1 for sgtl5000
  ARM: imx6q: add ssi1_ipg clk_lookup
  ARM: dts: imx6q-sabrelite: add audmux pinctrl support
  ARM: dts: imx6q-sabrelite: add i2c1 pinctrl support
  ARM: dts: imx6q-sabrelite: add audmux device
  ARM: dts: imx6q-sabrelite: add ssi device
  ARM: dts: imx6q-arm2: add pinctrl state for usdhc
  ARM: imx6: Add UART2 for low-level debug
  ARM: imx6q: register phy fixup only when CONFIG_PHYLIB is enabled
  ARM: imx6q: move imx6q_sabrelite specific code to a dedicated function
  ARM: dts: imx6q-sabrelite: Add SPI NOR support
  ARM: dts: Add basic support for imx6q-sabresd
  ...

Pulls in imx/pinctrl and imx/clock as dependencies.
Signed-off-by: NArnd Bergmann <arnd@arndb.de>
...@@ -37,6 +37,10 @@ i.MX6 Quad SABRE Lite Board ...@@ -37,6 +37,10 @@ i.MX6 Quad SABRE Lite Board
Required root node properties: Required root node properties:
- compatible = "fsl,imx6q-sabrelite", "fsl,imx6q"; - compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
i.MX6 Quad SABRE Smart Device Board
Required root node properties:
- compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
Generic i.MX boards Generic i.MX boards
------------------- -------------------
......
...@@ -14,7 +14,7 @@ Optional properties: ...@@ -14,7 +14,7 @@ Optional properties:
Example: Example:
fec@83fec000 { ethernet@83fec000 {
compatible = "fsl,imx51-fec", "fsl,imx27-fec"; compatible = "fsl,imx51-fec", "fsl,imx27-fec";
reg = <0x83fec000 0x4000>; reg = <0x83fec000 0x4000>;
interrupts = <87>; interrupts = <87>;
......
...@@ -11,7 +11,7 @@ Optional properties: ...@@ -11,7 +11,7 @@ Optional properties:
Example: Example:
uart@73fbc000 { serial@73fbc000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart"; compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x73fbc000 0x4000>; reg = <0x73fbc000 0x4000>;
interrupts = <31>; interrupts = <31>;
......
...@@ -180,6 +180,14 @@ choice ...@@ -180,6 +180,14 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
on i.MX50 or i.MX53. on i.MX50 or i.MX53.
config DEBUG_IMX6Q_UART2
bool "i.MX6Q Debug UART2"
depends on SOC_IMX6Q
help
Say Y here if you want kernel low-level debugging support
on i.MX6Q UART2. This is correct for e.g. the SabreLite
board.
config DEBUG_IMX6Q_UART4 config DEBUG_IMX6Q_UART4
bool "i.MX6Q Debug UART4" bool "i.MX6Q Debug UART4"
depends on SOC_IMX6Q depends on SOC_IMX6Q
......
...@@ -27,22 +27,22 @@ ...@@ -27,22 +27,22 @@
status = "okay"; status = "okay";
}; };
uart@1000a000 { serial@1000a000 {
fsl,uart-has-rtscts; fsl,uart-has-rtscts;
status = "okay"; status = "okay";
}; };
uart@1000b000 { serial@1000b000 {
fsl,uart-has-rtscts; fsl,uart-has-rtscts;
status = "okay"; status = "okay";
}; };
uart@1000c000 { serial@1000c000 {
fsl,uart-has-rtscts; fsl,uart-has-rtscts;
status = "okay"; status = "okay";
}; };
fec@1002b000 { ethernet@1002b000 {
status = "okay"; status = "okay";
}; };
......
...@@ -59,28 +59,28 @@ ...@@ -59,28 +59,28 @@
status = "disabled"; status = "disabled";
}; };
uart1: uart@1000a000 { uart1: serial@1000a000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart"; compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000a000 0x1000>; reg = <0x1000a000 0x1000>;
interrupts = <20>; interrupts = <20>;
status = "disabled"; status = "disabled";
}; };
uart2: uart@1000b000 { uart2: serial@1000b000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart"; compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000b000 0x1000>; reg = <0x1000b000 0x1000>;
interrupts = <19>; interrupts = <19>;
status = "disabled"; status = "disabled";
}; };
uart3: uart@1000c000 { uart3: serial@1000c000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart"; compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000c000 0x1000>; reg = <0x1000c000 0x1000>;
interrupts = <18>; interrupts = <18>;
status = "disabled"; status = "disabled";
}; };
uart4: uart@1000d000 { uart4: serial@1000d000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart"; compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000d000 0x1000>; reg = <0x1000d000 0x1000>;
interrupts = <17>; interrupts = <17>;
...@@ -183,14 +183,14 @@ ...@@ -183,14 +183,14 @@
status = "disabled"; status = "disabled";
}; };
uart5: uart@1001b000 { uart5: serial@1001b000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart"; compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1001b000 0x1000>; reg = <0x1001b000 0x1000>;
interrupts = <49>; interrupts = <49>;
status = "disabled"; status = "disabled";
}; };
uart6: uart@1001c000 { uart6: serial@1001c000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart"; compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1001c000 0x1000>; reg = <0x1001c000 0x1000>;
interrupts = <48>; interrupts = <48>;
...@@ -206,7 +206,7 @@ ...@@ -206,7 +206,7 @@
status = "disabled"; status = "disabled";
}; };
fec: fec@1002b000 { fec: ethernet@1002b000 {
compatible = "fsl,imx27-fec"; compatible = "fsl,imx27-fec";
reg = <0x1002b000 0x4000>; reg = <0x1002b000 0x4000>;
interrupts = <50>; interrupts = <50>;
......
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
model = "Freescale i.MX51 Babbage Board"; model = "Freescale i.MX51 Babbage Board";
compatible = "fsl,imx51-babbage", "fsl,imx51"; compatible = "fsl,imx51-babbage", "fsl,imx51";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
};
memory { memory {
reg = <0x90000000 0x20000000>; reg = <0x90000000 0x20000000>;
}; };
...@@ -40,7 +36,7 @@ ...@@ -40,7 +36,7 @@
status = "okay"; status = "okay";
}; };
uart3: uart@7000c000 { uart3: serial@7000c000 {
fsl,uart-has-rtscts; fsl,uart-has-rtscts;
status = "okay"; status = "okay";
}; };
...@@ -166,6 +162,11 @@ ...@@ -166,6 +162,11 @@
}; };
}; };
}; };
ssi2: ssi@70014000 {
fsl,mode = "i2s-slave";
status = "okay";
};
}; };
wdog@73f98000 { /* WDOG1 */ wdog@73f98000 { /* WDOG1 */
...@@ -177,12 +178,12 @@ ...@@ -177,12 +178,12 @@
reg = <0x73fa8000 0x4000>; reg = <0x73fa8000 0x4000>;
}; };
uart1: uart@73fbc000 { uart1: serial@73fbc000 {
fsl,uart-has-rtscts; fsl,uart-has-rtscts;
status = "okay"; status = "okay";
}; };
uart2: uart@73fc0000 { uart2: serial@73fc0000 {
status = "okay"; status = "okay";
}; };
}; };
...@@ -195,13 +196,20 @@ ...@@ -195,13 +196,20 @@
i2c@83fc4000 { /* I2C2 */ i2c@83fc4000 { /* I2C2 */
status = "okay"; status = "okay";
codec: sgtl5000@0a { sgtl5000: codec@0a {
compatible = "fsl,sgtl5000"; compatible = "fsl,sgtl5000";
reg = <0x0a>; reg = <0x0a>;
clock-frequency = <26000000>;
VDDA-supply = <&vdig_reg>;
VDDIO-supply = <&vvideo_reg>;
}; };
}; };
fec@83fec000 { audmux@83fd0000 {
status = "okay";
};
ethernet@83fec000 {
phy-mode = "mii"; phy-mode = "mii";
status = "okay"; status = "okay";
}; };
...@@ -218,4 +226,18 @@ ...@@ -218,4 +226,18 @@
gpio-key,wakeup; gpio-key,wakeup;
}; };
}; };
sound {
compatible = "fsl,imx51-babbage-sgtl5000",
"fsl,imx-audio-sgtl5000";
model = "imx51-babbage-sgtl5000";
ssi-controller = <&ssi2>;
audio-codec = <&sgtl5000>;
audio-routing =
"MIC_IN", "Mic Jack",
"Mic Jack", "Mic Bias",
"Headphone Jack", "HP_OUT";
mux-int-port = <2>;
mux-ext-port = <3>;
};
}; };
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
status = "disabled"; status = "disabled";
}; };
uart3: uart@7000c000 { uart3: serial@7000c000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart"; compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x7000c000 0x4000>; reg = <0x7000c000 0x4000>;
interrupts = <33>; interrupts = <33>;
...@@ -102,6 +102,15 @@ ...@@ -102,6 +102,15 @@
status = "disabled"; status = "disabled";
}; };
ssi2: ssi@70014000 {
compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
reg = <0x70014000 0x4000>;
interrupts = <30>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
status = "disabled";
};
esdhc@70020000 { /* ESDHC3 */ esdhc@70020000 { /* ESDHC3 */
compatible = "fsl,imx51-esdhc"; compatible = "fsl,imx51-esdhc";
reg = <0x70020000 0x4000>; reg = <0x70020000 0x4000>;
...@@ -171,14 +180,14 @@ ...@@ -171,14 +180,14 @@
status = "disabled"; status = "disabled";
}; };
uart1: uart@73fbc000 { uart1: serial@73fbc000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart"; compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x73fbc000 0x4000>; reg = <0x73fbc000 0x4000>;
interrupts = <31>; interrupts = <31>;
status = "disabled"; status = "disabled";
}; };
uart2: uart@73fc0000 { uart2: serial@73fc0000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart"; compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x73fc0000 0x4000>; reg = <0x73fc0000 0x4000>;
interrupts = <32>; interrupts = <32>;
...@@ -235,7 +244,31 @@ ...@@ -235,7 +244,31 @@
status = "disabled"; status = "disabled";
}; };
fec@83fec000 { ssi1: ssi@83fcc000 {
compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
reg = <0x83fcc000 0x4000>;
interrupts = <29>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
status = "disabled";
};
audmux@83fd0000 {
compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
reg = <0x83fd0000 0x4000>;
status = "disabled";
};
ssi3: ssi@83fe8000 {
compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
reg = <0x83fe8000 0x4000>;
interrupts = <96>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */
status = "disabled";
};
ethernet@83fec000 {
compatible = "fsl,imx51-fec", "fsl,imx27-fec"; compatible = "fsl,imx51-fec", "fsl,imx27-fec";
reg = <0x83fec000 0x4000>; reg = <0x83fec000 0x4000>;
interrupts = <87>; interrupts = <87>;
......
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Automotive Reference Design Board"; model = "Freescale i.MX53 Automotive Reference Design Board";
compatible = "fsl,imx53-ard", "fsl,imx53"; compatible = "fsl,imx53-ard", "fsl,imx53";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
};
memory { memory {
reg = <0x70000000 0x40000000>; reg = <0x70000000 0x40000000>;
}; };
...@@ -44,7 +40,7 @@ ...@@ -44,7 +40,7 @@
reg = <0x53fa8000 0x4000>; reg = <0x53fa8000 0x4000>;
}; };
uart1: uart@53fbc000 { uart1: serial@53fbc000 {
status = "okay"; status = "okay";
}; };
}; };
......
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Evaluation Kit"; model = "Freescale i.MX53 Evaluation Kit";
compatible = "fsl,imx53-evk", "fsl,imx53"; compatible = "fsl,imx53-evk", "fsl,imx53";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
};
memory { memory {
reg = <0x70000000 0x80000000>; reg = <0x70000000 0x80000000>;
}; };
...@@ -75,7 +71,7 @@ ...@@ -75,7 +71,7 @@
reg = <0x53fa8000 0x4000>; reg = <0x53fa8000 0x4000>;
}; };
uart1: uart@53fbc000 { uart1: serial@53fbc000 {
status = "okay"; status = "okay";
}; };
}; };
...@@ -99,7 +95,7 @@ ...@@ -99,7 +95,7 @@
}; };
}; };
fec@63fec000 { ethernet@63fec000 {
phy-mode = "rmii"; phy-mode = "rmii";
phy-reset-gpios = <&gpio7 6 0>; phy-reset-gpios = <&gpio7 6 0>;
status = "okay"; status = "okay";
......
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Quick Start Board"; model = "Freescale i.MX53 Quick Start Board";
compatible = "fsl,imx53-qsb", "fsl,imx53"; compatible = "fsl,imx53-qsb", "fsl,imx53";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
};
memory { memory {
reg = <0x70000000 0x40000000>; reg = <0x70000000 0x40000000>;
}; };
...@@ -33,6 +29,11 @@ ...@@ -33,6 +29,11 @@
status = "okay"; status = "okay";
}; };
ssi2: ssi@50014000 {
fsl,mode = "i2s-slave";
status = "okay";
};
esdhc@50020000 { /* ESDHC3 */ esdhc@50020000 { /* ESDHC3 */
cd-gpios = <&gpio3 11 0>; cd-gpios = <&gpio3 11 0>;
wp-gpios = <&gpio3 12 0>; wp-gpios = <&gpio3 12 0>;
...@@ -49,7 +50,7 @@ ...@@ -49,7 +50,7 @@
reg = <0x53fa8000 0x4000>; reg = <0x53fa8000 0x4000>;
}; };
uart1: uart@53fbc000 { uart1: serial@53fbc000 {
status = "okay"; status = "okay";
}; };
}; };
...@@ -62,9 +63,11 @@ ...@@ -62,9 +63,11 @@
i2c@63fc4000 { /* I2C2 */ i2c@63fc4000 { /* I2C2 */
status = "okay"; status = "okay";
codec: sgtl5000@0a { sgtl5000: codec@0a {
compatible = "fsl,sgtl5000"; compatible = "fsl,sgtl5000";
reg = <0x0a>; reg = <0x0a>;
VDDA-supply = <&reg_3p2v>;
VDDIO-supply = <&reg_3p2v>;
}; };
}; };
...@@ -77,12 +80,88 @@ ...@@ -77,12 +80,88 @@
}; };
pmic: dialog@48 { pmic: dialog@48 {
compatible = "dialog,da9053", "dialog,da9052"; compatible = "dlg,da9053-aa", "dlg,da9052";
reg = <0x48>; reg = <0x48>;
regulators {
buck0 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck1 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck2 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
buck3 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
ldo4 {
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1800000>;
};
ldo5 {
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1800000>;
};
ldo6 {
regulator-min-microvolt = <1725000>;
regulator-max-microvolt = <3300000>;
};
ldo7 {
regulator-min-microvolt = <1725000>;
regulator-max-microvolt = <3300000>;
};
ldo8 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
};
ldo9 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
};
ldo10 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
};
ldo11 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
};
ldo12 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3650000>;
};
ldo13 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3600000>;
};
};
}; };
}; };
fec@63fec000 { audmux@63fd0000 {
status = "okay";
};
ethernet@63fec000 {
phy-mode = "rmii"; phy-mode = "rmii";
phy-reset-gpios = <&gpio7 6 0>; phy-reset-gpios = <&gpio7 6 0>;
status = "okay"; status = "okay";
...@@ -122,4 +201,30 @@ ...@@ -122,4 +201,30 @@
linux,default-trigger = "heartbeat"; linux,default-trigger = "heartbeat";
}; };
}; };
regulators {
compatible = "simple-bus";
reg_3p2v: 3p2v {
compatible = "regulator-fixed";
regulator-name = "3P2V";
regulator-min-microvolt = <3200000>;
regulator-max-microvolt = <3200000>;
regulator-always-on;
};
};
sound {
compatible = "fsl,imx53-qsb-sgtl5000",
"fsl,imx-audio-sgtl5000";
model = "imx53-qsb-sgtl5000";
ssi-controller = <&ssi2>;
audio-codec = <&sgtl5000>;
audio-routing =
"MIC_IN", "Mic Jack",
"Mic Jack", "Mic Bias",
"Headphone Jack", "HP_OUT";
mux-int-port = <2>;
mux-ext-port = <5>;
};
}; };
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Smart Mobile Reference Design Board"; model = "Freescale i.MX53 Smart Mobile Reference Design Board";
compatible = "fsl,imx53-smd", "fsl,imx53"; compatible = "fsl,imx53-smd", "fsl,imx53";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
};
memory { memory {
reg = <0x70000000 0x40000000>; reg = <0x70000000 0x40000000>;
}; };
...@@ -39,7 +35,7 @@ ...@@ -39,7 +35,7 @@
status = "okay"; status = "okay";
}; };
uart3: uart@5000c000 { uart3: serial@5000c000 {
fsl,uart-has-rtscts; fsl,uart-has-rtscts;
status = "okay"; status = "okay";
}; };
...@@ -90,11 +86,11 @@ ...@@ -90,11 +86,11 @@
reg = <0x53fa8000 0x4000>; reg = <0x53fa8000 0x4000>;
}; };
uart1: uart@53fbc000 { uart1: serial@53fbc000 {
status = "okay"; status = "okay";
}; };
uart2: uart@53fc0000 { uart2: serial@53fc0000 {
status = "okay"; status = "okay";
}; };
}; };
...@@ -142,7 +138,7 @@ ...@@ -142,7 +138,7 @@
}; };
}; };
fec@63fec000 { ethernet@63fec000 {
phy-mode = "rmii"; phy-mode = "rmii";
phy-reset-gpios = <&gpio7 6 0>; phy-reset-gpios = <&gpio7 6 0>;
status = "okay"; status = "okay";
......
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
status = "disabled"; status = "disabled";
}; };
uart3: uart@5000c000 { uart3: serial@5000c000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart"; compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x5000c000 0x4000>; reg = <0x5000c000 0x4000>;
interrupts = <33>; interrupts = <33>;
...@@ -104,6 +104,15 @@ ...@@ -104,6 +104,15 @@
status = "disabled"; status = "disabled";
}; };
ssi2: ssi@50014000 {
compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
reg = <0x50014000 0x4000>;
interrupts = <30>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
status = "disabled";
};
esdhc@50020000 { /* ESDHC3 */ esdhc@50020000 { /* ESDHC3 */
compatible = "fsl,imx53-esdhc"; compatible = "fsl,imx53-esdhc";
reg = <0x50020000 0x4000>; reg = <0x50020000 0x4000>;
...@@ -173,14 +182,14 @@ ...@@ -173,14 +182,14 @@
status = "disabled"; status = "disabled";
}; };
uart1: uart@53fbc000 { uart1: serial@53fbc000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart"; compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x53fbc000 0x4000>; reg = <0x53fbc000 0x4000>;
interrupts = <31>; interrupts = <31>;
status = "disabled"; status = "disabled";
}; };
uart2: uart@53fc0000 { uart2: serial@53fc0000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart"; compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x53fc0000 0x4000>; reg = <0x53fc0000 0x4000>;
interrupts = <32>; interrupts = <32>;
...@@ -226,7 +235,7 @@ ...@@ -226,7 +235,7 @@
status = "disabled"; status = "disabled";
}; };
uart4: uart@53ff0000 { uart4: serial@53ff0000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart"; compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x53ff0000 0x4000>; reg = <0x53ff0000 0x4000>;
interrupts = <13>; interrupts = <13>;
...@@ -241,7 +250,7 @@ ...@@ -241,7 +250,7 @@
reg = <0x60000000 0x10000000>; reg = <0x60000000 0x10000000>;
ranges; ranges;
uart5: uart@63f90000 { uart5: serial@63f90000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart"; compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x63f90000 0x4000>; reg = <0x63f90000 0x4000>;
interrupts = <86>; interrupts = <86>;
...@@ -290,7 +299,31 @@ ...@@ -290,7 +299,31 @@
status = "disabled"; status = "disabled";
}; };
fec@63fec000 { ssi1: ssi@63fcc000 {
compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
reg = <0x63fcc000 0x4000>;
interrupts = <29>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
status = "disabled";
};
audmux@63fd0000 {
compatible = "fsl,imx53-audmux", "fsl,imx31-audmux";
reg = <0x63fd0000 0x4000>;
status = "disabled";
};
ssi3: ssi@63fe8000 {
compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
reg = <0x63fe8000 0x4000>;
interrupts = <96>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <47 46 45 44>; /* TX0 RX0 TX1 RX1 */
status = "disabled";
};
ethernet@63fec000 {
compatible = "fsl,imx53-fec", "fsl,imx25-fec"; compatible = "fsl,imx53-fec", "fsl,imx25-fec";
reg = <0x63fec000 0x4000>; reg = <0x63fec000 0x4000>;
interrupts = <87>; interrupts = <87>;
......
...@@ -17,19 +17,14 @@ ...@@ -17,19 +17,14 @@
model = "Freescale i.MX6 Quad Armadillo2 Board"; model = "Freescale i.MX6 Quad Armadillo2 Board";
compatible = "fsl,imx6q-arm2", "fsl,imx6q"; compatible = "fsl,imx6q-arm2", "fsl,imx6q";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait";
};
memory { memory {
reg = <0x10000000 0x80000000>; reg = <0x10000000 0x80000000>;
}; };
soc { soc {
aips-bus@02100000 { /* AIPS2 */ aips-bus@02100000 { /* AIPS2 */
enet@02188000 { ethernet@02188000 {
phy-mode = "rgmii"; phy-mode = "rgmii";
local-mac-address = [00 04 9F 01 1B 61];
status = "okay"; status = "okay";
}; };
...@@ -37,16 +32,20 @@ ...@@ -37,16 +32,20 @@
cd-gpios = <&gpio6 11 0>; cd-gpios = <&gpio6 11 0>;
wp-gpios = <&gpio6 14 0>; wp-gpios = <&gpio6 14 0>;
vmmc-supply = <&reg_3p3v>; vmmc-supply = <&reg_3p3v>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc3_1>;
status = "okay"; status = "okay";
}; };
usdhc@0219c000 { /* uSDHC4 */ usdhc@0219c000 { /* uSDHC4 */
fsl,card-wired; fsl,card-wired;
vmmc-supply = <&reg_3p3v>; vmmc-supply = <&reg_3p3v>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4_1>;
status = "okay"; status = "okay";
}; };
uart4: uart@021f0000 { uart4: serial@021f0000 {
status = "okay"; status = "okay";
}; };
}; };
......
...@@ -22,8 +22,30 @@ ...@@ -22,8 +22,30 @@
}; };
soc { soc {
aips-bus@02000000 { /* AIPS1 */
spba-bus@02000000 {
ecspi@02008000 { /* eCSPI1 */
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio3 19 0>;
status = "okay";
flash: m25p80@0 {
compatible = "sst,sst25vf016b";
spi-max-frequency = <20000000>;
reg = <0>;
};
};
ssi1: ssi@02028000 {
fsl,mode = "i2s-slave";
status = "okay";
};
};
};
aips-bus@02100000 { /* AIPS2 */ aips-bus@02100000 { /* AIPS2 */
enet@02188000 { ethernet@02188000 {
phy-mode = "rgmii"; phy-mode = "rgmii";
phy-reset-gpios = <&gpio3 23 0>; phy-reset-gpios = <&gpio3 23 0>;
status = "okay"; status = "okay";
...@@ -43,13 +65,23 @@ ...@@ -43,13 +65,23 @@
status = "okay"; status = "okay";
}; };
uart2: uart@021e8000 { audmux@021d8000 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_audmux_1>;
};
uart2: serial@021e8000 {
status = "okay"; status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_serial2_1>;
}; };
i2c@021a0000 { /* I2C1 */ i2c@021a0000 { /* I2C1 */
status = "okay"; status = "okay";
clock-frequency = <100000>; clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1_1>;
codec: sgtl5000@0a { codec: sgtl5000@0a {
compatible = "fsl,sgtl5000"; compatible = "fsl,sgtl5000";
...@@ -80,4 +112,18 @@ ...@@ -80,4 +112,18 @@
regulator-always-on; regulator-always-on;
}; };
}; };
sound {
compatible = "fsl,imx6q-sabrelite-sgtl5000",
"fsl,imx-audio-sgtl5000";
model = "imx6q-sabrelite-sgtl5000";
ssi-controller = <&ssi1>;
audio-codec = <&codec>;
audio-routing =
"MIC_IN", "Mic Jack",
"Mic Jack", "Mic Bias",
"Headphone Jack", "HP_OUT";
mux-int-port = <1>;
mux-ext-port = <4>;
};
}; };
/*
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
/dts-v1/;
/include/ "imx6q.dtsi"
/ {
model = "Freescale i.MX6Q SABRE Smart Device Board";
compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
memory {
reg = <0x10000000 0x40000000>;
};
soc {
aips-bus@02000000 { /* AIPS1 */
spba-bus@02000000 {
uart1: serial@02020000 {
status = "okay";
};
};
};
aips-bus@02100000 { /* AIPS2 */
ethernet@02188000 {
phy-mode = "rgmii";
status = "okay";
};
usdhc@02194000 { /* uSDHC2 */
cd-gpios = <&gpio2 2 0>;
wp-gpios = <&gpio2 3 0>;
status = "okay";
};
usdhc@02198000 { /* uSDHC3 */
cd-gpios = <&gpio2 0 0>;
wp-gpios = <&gpio2 1 0>;
status = "okay";
};
};
};
};
...@@ -165,7 +165,7 @@ ...@@ -165,7 +165,7 @@
status = "disabled"; status = "disabled";
}; };
uart1: uart@02020000 { uart1: serial@02020000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02020000 0x4000>; reg = <0x02020000 0x4000>;
interrupts = <0 26 0x04>; interrupts = <0 26 0x04>;
...@@ -177,19 +177,31 @@ ...@@ -177,19 +177,31 @@
interrupts = <0 51 0x04>; interrupts = <0 51 0x04>;
}; };
ssi@02028000 { /* SSI1 */ ssi1: ssi@02028000 {
compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
reg = <0x02028000 0x4000>; reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>; interrupts = <0 46 0x04>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <38 37>;
status = "disabled";
}; };
ssi@0202c000 { /* SSI2 */ ssi2: ssi@0202c000 {
compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
reg = <0x0202c000 0x4000>; reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>; interrupts = <0 47 0x04>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <42 41>;
status = "disabled";
}; };
ssi@02030000 { /* SSI3 */ ssi3: ssi@02030000 {
compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
reg = <0x02030000 0x4000>; reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>; interrupts = <0 48 0x04>;
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <46 45>;
status = "disabled";
}; };
asrc@02034000 { asrc@02034000 {
...@@ -346,6 +358,90 @@ ...@@ -346,6 +358,90 @@
compatible = "fsl,imx6q-anatop"; compatible = "fsl,imx6q-anatop";
reg = <0x020c8000 0x1000>; reg = <0x020c8000 0x1000>;
interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
regulator-1p1@110 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd1p1";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1375000>;
regulator-always-on;
anatop-reg-offset = <0x110>;
anatop-vol-bit-shift = <8>;
anatop-vol-bit-width = <5>;
anatop-min-bit-val = <4>;
anatop-min-voltage = <800000>;
anatop-max-voltage = <1375000>;
};
regulator-3p0@120 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd3p0";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <3150000>;
regulator-always-on;
anatop-reg-offset = <0x120>;
anatop-vol-bit-shift = <8>;
anatop-vol-bit-width = <5>;
anatop-min-bit-val = <0>;
anatop-min-voltage = <2625000>;
anatop-max-voltage = <3400000>;
};
regulator-2p5@130 {
compatible = "fsl,anatop-regulator";
regulator-name = "vdd2p5";
regulator-min-microvolt = <2000000>;
regulator-max-microvolt = <2750000>;
regulator-always-on;
anatop-reg-offset = <0x130>;
anatop-vol-bit-shift = <8>;
anatop-vol-bit-width = <5>;
anatop-min-bit-val = <0>;
anatop-min-voltage = <2000000>;
anatop-max-voltage = <2750000>;
};
regulator-vddcore@140 {
compatible = "fsl,anatop-regulator";
regulator-name = "cpu";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1450000>;
regulator-always-on;
anatop-reg-offset = <0x140>;
anatop-vol-bit-shift = <0>;
anatop-vol-bit-width = <5>;
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
};
regulator-vddpu@140 {
compatible = "fsl,anatop-regulator";
regulator-name = "vddpu";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1450000>;
regulator-always-on;
anatop-reg-offset = <0x140>;
anatop-vol-bit-shift = <9>;
anatop-vol-bit-width = <5>;
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
};
regulator-vddsoc@140 {
compatible = "fsl,anatop-regulator";
regulator-name = "vddsoc";
regulator-min-microvolt = <725000>;
regulator-max-microvolt = <1450000>;
regulator-always-on;
anatop-reg-offset = <0x140>;
anatop-vol-bit-shift = <18>;
anatop-vol-bit-width = <5>;
anatop-min-bit-val = <1>;
anatop-min-voltage = <725000>;
anatop-max-voltage = <1450000>;
};
}; };
usbphy@020c9000 { /* USBPHY1 */ usbphy@020c9000 { /* USBPHY1 */
...@@ -386,7 +482,62 @@ ...@@ -386,7 +482,62 @@
}; };
iomuxc@020e0000 { iomuxc@020e0000 {
compatible = "fsl,imx6q-iomuxc";
reg = <0x020e0000 0x4000>; reg = <0x020e0000 0x4000>;
/* shared pinctrl settings */
audmux {
pinctrl_audmux_1: audmux-1 {
fsl,pins = <18 0x80000000 /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */
1586 0x80000000 /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */
11 0x80000000 /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */
3 0x80000000>; /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
};
};
i2c1 {
pinctrl_i2c1_1: i2c1grp-1 {
fsl,pins = <137 0x4001b8b1 /* MX6Q_PAD_EIM_D21__I2C1_SCL */
196 0x4001b8b1>; /* MX6Q_PAD_EIM_D28__I2C1_SDA */
};
};
serial2 {
pinctrl_serial2_1: serial2grp-1 {
fsl,pins = <183 0x1b0b1 /* MX6Q_PAD_EIM_D26__UART2_TXD */
191 0x1b0b1>; /* MX6Q_PAD_EIM_D27__UART2_RXD */
};
};
usdhc3 {
pinctrl_usdhc3_1: usdhc3grp-1 {
fsl,pins = <1273 0x17059 /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
1281 0x10059 /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
1289 0x17059 /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
1297 0x17059 /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
1305 0x17059 /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
1312 0x17059 /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
1265 0x17059 /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */
1257 0x17059 /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */
1249 0x17059 /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */
1241 0x17059>; /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */
};
};
usdhc4 {
pinctrl_usdhc4_1: usdhc4grp-1 {
fsl,pins = <1386 0x17059 /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
1392 0x10059 /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
1462 0x17059 /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
1470 0x17059 /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
1478 0x17059 /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
1486 0x17059 /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
1493 0x17059 /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
1501 0x17059 /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
1509 0x17059 /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
1517 0x17059>; /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
};
};
}; };
dcic@020e4000 { /* DCIC1 */ dcic@020e4000 { /* DCIC1 */
...@@ -422,7 +573,7 @@ ...@@ -422,7 +573,7 @@
reg = <0x0217c000 0x4000>; reg = <0x0217c000 0x4000>;
}; };
enet@02188000 { ethernet@02188000 {
compatible = "fsl,imx6q-fec"; compatible = "fsl,imx6q-fec";
reg = <0x02188000 0x4000>; reg = <0x02188000 0x4000>;
interrupts = <0 118 0x04 0 119 0x04>; interrupts = <0 118 0x04 0 119 0x04>;
...@@ -527,7 +678,9 @@ ...@@ -527,7 +678,9 @@
}; };
audmux@021d8000 { audmux@021d8000 {
compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
reg = <0x021d8000 0x4000>; reg = <0x021d8000 0x4000>;
status = "disabled";
}; };
mipi@021dc000 { /* MIPI-CSI */ mipi@021dc000 { /* MIPI-CSI */
...@@ -543,28 +696,28 @@ ...@@ -543,28 +696,28 @@
interrupts = <0 18 0x04>; interrupts = <0 18 0x04>;
}; };
uart2: uart@021e8000 { uart2: serial@021e8000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021e8000 0x4000>; reg = <0x021e8000 0x4000>;
interrupts = <0 27 0x04>; interrupts = <0 27 0x04>;
status = "disabled"; status = "disabled";
}; };
uart3: uart@021ec000 { uart3: serial@021ec000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021ec000 0x4000>; reg = <0x021ec000 0x4000>;
interrupts = <0 28 0x04>; interrupts = <0 28 0x04>;
status = "disabled"; status = "disabled";
}; };
uart4: uart@021f0000 { uart4: serial@021f0000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f0000 0x4000>; reg = <0x021f0000 0x4000>;
interrupts = <0 29 0x04>; interrupts = <0 29 0x04>;
status = "disabled"; status = "disabled";
}; };
uart5: uart@021f4000 { uart5: serial@021f4000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f4000 0x4000>; reg = <0x021f4000 0x4000>;
interrupts = <0 30 0x04>; interrupts = <0 30 0x04>;
......
...@@ -34,6 +34,7 @@ config ARCH_MX53 ...@@ -34,6 +34,7 @@ config ARCH_MX53
config SOC_IMX1 config SOC_IMX1
bool bool
select ARCH_MX1 select ARCH_MX1
select COMMON_CLK
select CPU_ARM920T select CPU_ARM920T
select IMX_HAVE_IOMUX_V1 select IMX_HAVE_IOMUX_V1
select MXC_AVIC select MXC_AVIC
...@@ -42,12 +43,14 @@ config SOC_IMX21 ...@@ -42,12 +43,14 @@ config SOC_IMX21
bool bool
select MACH_MX21 select MACH_MX21
select CPU_ARM926T select CPU_ARM926T
select COMMON_CLK
select IMX_HAVE_IOMUX_V1 select IMX_HAVE_IOMUX_V1
select MXC_AVIC select MXC_AVIC
config SOC_IMX25 config SOC_IMX25
bool bool
select ARCH_MX25 select ARCH_MX25
select COMMON_CLK
select CPU_ARM926T select CPU_ARM926T
select ARCH_MXC_IOMUX_V3 select ARCH_MXC_IOMUX_V3
select MXC_AVIC select MXC_AVIC
...@@ -56,6 +59,7 @@ config SOC_IMX27 ...@@ -56,6 +59,7 @@ config SOC_IMX27
bool bool
select MACH_MX27 select MACH_MX27
select CPU_ARM926T select CPU_ARM926T
select COMMON_CLK
select IMX_HAVE_IOMUX_V1 select IMX_HAVE_IOMUX_V1
select MXC_AVIC select MXC_AVIC
...@@ -64,12 +68,14 @@ config SOC_IMX31 ...@@ -64,12 +68,14 @@ config SOC_IMX31
select CPU_V6 select CPU_V6
select IMX_HAVE_PLATFORM_MXC_RNGA select IMX_HAVE_PLATFORM_MXC_RNGA
select MXC_AVIC select MXC_AVIC
select COMMON_CLK
select SMP_ON_UP if SMP select SMP_ON_UP if SMP
config SOC_IMX35 config SOC_IMX35
bool bool
select CPU_V6 select CPU_V6
select ARCH_MXC_IOMUX_V3 select ARCH_MXC_IOMUX_V3
select COMMON_CLK
select HAVE_EPIT select HAVE_EPIT
select MXC_AVIC select MXC_AVIC
select SMP_ON_UP if SMP select SMP_ON_UP if SMP
...@@ -77,6 +83,7 @@ config SOC_IMX35 ...@@ -77,6 +83,7 @@ config SOC_IMX35
config SOC_IMX5 config SOC_IMX5
select CPU_V7 select CPU_V7
select MXC_TZIC select MXC_TZIC
select COMMON_CLK
select ARCH_MXC_IOMUX_V3 select ARCH_MXC_IOMUX_V3
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
select ARCH_MX5 select ARCH_MX5
...@@ -836,6 +843,7 @@ config SOC_IMX6Q ...@@ -836,6 +843,7 @@ config SOC_IMX6Q
bool "i.MX6 Quad support" bool "i.MX6 Quad support"
select ARM_CPU_SUSPEND if PM select ARM_CPU_SUSPEND if PM
select ARM_GIC select ARM_GIC
select COMMON_CLK
select CPU_V7 select CPU_V7
select HAVE_ARM_SCU select HAVE_ARM_SCU
select HAVE_IMX_GPC select HAVE_IMX_GPC
......
obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
clk-pfd.o clk-busy.o
# Support for CMOS sensor interface # Support for CMOS sensor interface
obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
...@@ -70,7 +73,7 @@ obj-$(CONFIG_CPU_V7) += head-v7.o ...@@ -70,7 +73,7 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
AFLAGS_head-v7.o :=-Wa,-march=armv7-a AFLAGS_head-v7.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
ifeq ($(CONFIG_PM),y) ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
......
...@@ -42,4 +42,5 @@ dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb ...@@ -42,4 +42,5 @@ dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb
dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \ dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \
imx53-qsb.dtb imx53-smd.dtb imx53-qsb.dtb imx53-smd.dtb
dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \ dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \
imx6q-sabrelite.dtb imx6q-sabrelite.dtb \
imx6q-sabresd.dtb \
/*
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/err.h>
#include "clk.h"
static int clk_busy_wait(void __iomem *reg, u8 shift)
{
unsigned long timeout = jiffies + msecs_to_jiffies(10);
while (readl_relaxed(reg) & (1 << shift))
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
return 0;
}
struct clk_busy_divider {
struct clk_divider div;
const struct clk_ops *div_ops;
void __iomem *reg;
u8 shift;
};
static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
{
struct clk_divider *div = container_of(hw, struct clk_divider, hw);
return container_of(div, struct clk_busy_divider, div);
}
static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_busy_divider *busy = to_clk_busy_divider(hw);
return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
}
static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_busy_divider *busy = to_clk_busy_divider(hw);
return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
}
static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_busy_divider *busy = to_clk_busy_divider(hw);
int ret;
ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate);
if (!ret)
ret = clk_busy_wait(busy->reg, busy->shift);
return ret;
}
static struct clk_ops clk_busy_divider_ops = {
.recalc_rate = clk_busy_divider_recalc_rate,
.round_rate = clk_busy_divider_round_rate,
.set_rate = clk_busy_divider_set_rate,
};
struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
void __iomem *reg, u8 shift, u8 width,
void __iomem *busy_reg, u8 busy_shift)
{
struct clk_busy_divider *busy;
struct clk *clk;
struct clk_init_data init;
busy = kzalloc(sizeof(*busy), GFP_KERNEL);
if (!busy)
return ERR_PTR(-ENOMEM);
busy->reg = busy_reg;
busy->shift = busy_shift;
busy->div.reg = reg;
busy->div.shift = shift;
busy->div.width = width;
busy->div.lock = &imx_ccm_lock;
busy->div_ops = &clk_divider_ops;
init.name = name;
init.ops = &clk_busy_divider_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = &parent_name;
init.num_parents = 1;
busy->div.hw.init = &init;
clk = clk_register(NULL, &busy->div.hw);
if (!clk)
kfree(busy);
return clk;
}
struct clk_busy_mux {
struct clk_mux mux;
const struct clk_ops *mux_ops;
void __iomem *reg;
u8 shift;
};
static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
{
struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
return container_of(mux, struct clk_busy_mux, mux);
}
static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
{
struct clk_busy_mux *busy = to_clk_busy_mux(hw);
return busy->mux_ops->get_parent(&busy->mux.hw);
}
static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_busy_mux *busy = to_clk_busy_mux(hw);
int ret;
ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
if (!ret)
ret = clk_busy_wait(busy->reg, busy->shift);
return ret;
}
struct clk_ops clk_busy_mux_ops = {
.get_parent = clk_busy_mux_get_parent,
.set_parent = clk_busy_mux_set_parent,
};
struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
u8 width, void __iomem *busy_reg, u8 busy_shift,
const char **parent_names, int num_parents)
{
struct clk_busy_mux *busy;
struct clk *clk;
struct clk_init_data init;
busy = kzalloc(sizeof(*busy), GFP_KERNEL);
if (!busy)
return ERR_PTR(-ENOMEM);
busy->reg = busy_reg;
busy->shift = busy_shift;
busy->mux.reg = reg;
busy->mux.shift = shift;
busy->mux.width = width;
busy->mux.lock = &imx_ccm_lock;
busy->mux_ops = &clk_mux_ops;
init.name = name;
init.ops = &clk_busy_mux_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
busy->mux.hw.init = &init;
clk = clk_register(NULL, &busy->mux.hw);
if (IS_ERR(clk))
kfree(busy);
return clk;
}
/*
* Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
* Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Gated clock implementation
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/string.h>
/**
* DOC: basic gatable clock which can gate and ungate it's ouput
*
* Traits of this clock:
* prepare - clk_(un)prepare only ensures parent is (un)prepared
* enable - clk_enable and clk_disable are functional & control gating
* rate - inherits rate from parent. No clk_set_rate support
* parent - fixed parent. No clk_set_parent support
*/
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
static int clk_gate2_enable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
u32 reg;
unsigned long flags = 0;
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
reg = readl(gate->reg);
reg |= 3 << gate->bit_idx;
writel(reg, gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
return 0;
}
static void clk_gate2_disable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
u32 reg;
unsigned long flags = 0;
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
reg = readl(gate->reg);
reg &= ~(3 << gate->bit_idx);
writel(reg, gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
}
static int clk_gate2_is_enabled(struct clk_hw *hw)
{
u32 reg;
struct clk_gate *gate = to_clk_gate(hw);
reg = readl(gate->reg);
if (((reg >> gate->bit_idx) & 3) == 3)
return 1;
return 0;
}
static struct clk_ops clk_gate2_ops = {
.enable = clk_gate2_enable,
.disable = clk_gate2_disable,
.is_enabled = clk_gate2_is_enabled,
};
struct clk *clk_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate2_flags, spinlock_t *lock)
{
struct clk_gate *gate;
struct clk *clk;
struct clk_init_data init;
gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
if (!gate)
return ERR_PTR(-ENOMEM);
/* struct clk_gate assignments */
gate->reg = reg;
gate->bit_idx = bit_idx;
gate->flags = clk_gate2_flags;
gate->lock = lock;
init.name = name;
init.ops = &clk_gate2_ops;
init.flags = flags;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
gate->hw.init = &init;
clk = clk_register(dev, &gate->hw);
if (IS_ERR(clk))
kfree(clk);
return clk;
}
/*
* Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include "clk.h"
/* CCM register addresses */
#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
#define CCM_CSCR IO_ADDR_CCM(0x0)
#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
#define CCM_PCDR IO_ADDR_CCM(0x20)
/* SCM register addresses */
#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
#define SCM_GCCR IO_ADDR_SCM(0xc)
static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", "prem",
"fclk", };
enum imx1_clks {
dummy, clk32, clk16m_ext, clk16m, clk32_premult, prem, mpll, spll, mcu,
fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
mma_gate, usbd_gate, clk_max
};
static struct clk *clk[clk_max];
int __init mx1_clocks_init(unsigned long fref)
{
int i;
clk[dummy] = imx_clk_fixed("dummy", 0);
clk[clk32] = imx_clk_fixed("clk32", fref);
clk[clk16m_ext] = imx_clk_fixed("clk16m_ext", 16000000);
clk[clk16m] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
clk[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
clk[prem] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks,
ARRAY_SIZE(prem_sel_clks));
clk[mpll] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
clk[spll] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
clk[mcu] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 15, 1);
clk[hclk] = imx_clk_divider("hclk", "spll", CCM_CSCR, 10, 4);
clk[clk48m] = imx_clk_divider("clk48m", "spll", CCM_CSCR, 26, 3);
clk[per1] = imx_clk_divider("per1", "spll", CCM_PCDR, 0, 4);
clk[per2] = imx_clk_divider("per2", "spll", CCM_PCDR, 4, 4);
clk[per3] = imx_clk_divider("per3", "spll", CCM_PCDR, 16, 7);
clk[clko] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks,
ARRAY_SIZE(clko_sel_clks));
clk[dma_gate] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 4);
clk[csi_gate] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
clk[mma_gate] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
clk[usbd_gate] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
for (i = 0; i < ARRAY_SIZE(clk); i++)
if (IS_ERR(clk[i]))
pr_err("imx1 clk %d: register failed with %ld\n",
i, PTR_ERR(clk[i]));
clk_register_clkdev(clk[dma_gate], "ahb", "imx-dma");
clk_register_clkdev(clk[csi_gate], NULL, "mx1-camera.0");
clk_register_clkdev(clk[mma_gate], "mma", NULL);
clk_register_clkdev(clk[usbd_gate], NULL, "imx_udc.0");
clk_register_clkdev(clk[per1], "per", "imx-gpt.0");
clk_register_clkdev(clk[hclk], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[per1], "per", "imx1-uart.0");
clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.0");
clk_register_clkdev(clk[per1], "per", "imx1-uart.1");
clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.1");
clk_register_clkdev(clk[per1], "per", "imx1-uart.2");
clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.2");
clk_register_clkdev(clk[hclk], NULL, "imx-i2c.0");
clk_register_clkdev(clk[per2], "per", "imx1-cspi.0");
clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.0");
clk_register_clkdev(clk[per2], "per", "imx1-cspi.1");
clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.1");
clk_register_clkdev(clk[per2], NULL, "imx-mmc.0");
clk_register_clkdev(clk[per2], "per", "imx-fb.0");
clk_register_clkdev(clk[dummy], "ipg", "imx-fb.0");
clk_register_clkdev(clk[dummy], "ahb", "imx-fb.0");
clk_register_clkdev(clk[hclk], "mshc", NULL);
clk_register_clkdev(clk[per3], "ssi", NULL);
clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0");
clk_register_clkdev(clk[clko], "clko", NULL);
mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
MX1_TIM1_INT);
return 0;
}
/*
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
* Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include "clk.h"
#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
/* Register offsets */
#define CCM_CSCR IO_ADDR_CCM(0x0)
#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
#define CCM_PCDR0 IO_ADDR_CCM(0x18)
#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
#define CCM_PCCR0 IO_ADDR_CCM(0x20)
#define CCM_PCCR1 IO_ADDR_CCM(0x24)
#define CCM_CCSR IO_ADDR_CCM(0x28)
#define CCM_PMCTL IO_ADDR_CCM(0x2c)
#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
static const char *mpll_sel_clks[] = { "fpm", "ckih", };
static const char *spll_sel_clks[] = { "fpm", "ckih", };
enum imx21_clks {
ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
per2, per3, per4, uart1_ipg_gate, uart2_ipg_gate, uart3_ipg_gate,
uart4_ipg_gate, gpt1_ipg_gate, gpt2_ipg_gate, gpt3_ipg_gate,
pwm_ipg_gate, sdhc1_ipg_gate, sdhc2_ipg_gate, lcdc_ipg_gate,
lcdc_hclk_gate, cspi3_ipg_gate, cspi2_ipg_gate, cspi1_ipg_gate,
per4_gate, csi_hclk_gate, usb_div, usb_gate, usb_hclk_gate, ssi1_gate,
ssi2_gate, nfc_div, nfc_gate, dma_gate, dma_hclk_gate, brom_gate,
emma_gate, emma_hclk_gate, slcdc_gate, slcdc_hclk_gate, wdog_gate,
gpio_gate, i2c_gate, kpp_gate, owire_gate, rtc_gate, clk_max
};
static struct clk *clk[clk_max];
/*
* must be called very early to get information about the
* available clock rate when the timer framework starts
*/
int __init mx21_clocks_init(unsigned long lref, unsigned long href)
{
int i;
clk[ckil] = imx_clk_fixed("ckil", lref);
clk[ckih] = imx_clk_fixed("ckih", href);
clk[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
clk[mpll_sel] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks,
ARRAY_SIZE(mpll_sel_clks));
clk[spll_sel] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks,
ARRAY_SIZE(spll_sel_clks));
clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
clk[spll] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0);
clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 29, 3);
clk[hclk] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
clk[ipg] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
clk[per1] = imx_clk_divider("per1", "mpll", CCM_PCDR1, 0, 6);
clk[per2] = imx_clk_divider("per2", "mpll", CCM_PCDR1, 8, 6);
clk[per3] = imx_clk_divider("per3", "mpll", CCM_PCDR1, 16, 6);
clk[per4] = imx_clk_divider("per4", "mpll", CCM_PCDR1, 24, 6);
clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
clk[lcdc_hclk_gate] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
clk[per4_gate] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
clk[csi_hclk_gate] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 26, 3);
clk[usb_gate] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
clk[usb_hclk_gate] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
clk[ssi1_gate] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
clk[ssi2_gate] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
clk[nfc_div] = imx_clk_divider("nfc_div", "ipg", CCM_PCDR0, 12, 4);
clk[nfc_gate] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
clk[dma_gate] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
clk[dma_hclk_gate] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
clk[brom_gate] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
clk[emma_gate] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
clk[emma_hclk_gate] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
clk[slcdc_gate] = imx_clk_gate("slcdc_gate", "ipg", CCM_PCCR0, 25);
clk[slcdc_hclk_gate] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
clk[wdog_gate] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
clk[gpio_gate] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
clk[i2c_gate] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
clk[kpp_gate] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
clk[owire_gate] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
clk[rtc_gate] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
for (i = 0; i < ARRAY_SIZE(clk); i++)
if (IS_ERR(clk[i]))
pr_err("i.MX21 clk %d: register failed with %ld\n",
i, PTR_ERR(clk[i]));
clk_register_clkdev(clk[per1], "per1", NULL);
clk_register_clkdev(clk[per2], "per2", NULL);
clk_register_clkdev(clk[per3], "per3", NULL);
clk_register_clkdev(clk[per4], "per4", NULL);
clk_register_clkdev(clk[per1], "per", "imx21-uart.0");
clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
clk_register_clkdev(clk[per1], "per", "imx21-uart.1");
clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
clk_register_clkdev(clk[per1], "per", "imx21-uart.2");
clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
clk_register_clkdev(clk[per1], "per", "imx21-uart.3");
clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[per1], "per", "imx-gpt.0");
clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1");
clk_register_clkdev(clk[per1], "per", "imx-gpt.1");
clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
clk_register_clkdev(clk[per1], "per", "imx-gpt.2");
clk_register_clkdev(clk[pwm_ipg_gate], "pwm", "mxc_pwm.0");
clk_register_clkdev(clk[per2], "per", "imx21-cspi.0");
clk_register_clkdev(clk[cspi1_ipg_gate], "ipg", "imx21-cspi.0");
clk_register_clkdev(clk[per2], "per", "imx21-cspi.1");
clk_register_clkdev(clk[cspi2_ipg_gate], "ipg", "imx21-cspi.1");
clk_register_clkdev(clk[per2], "per", "imx21-cspi.2");
clk_register_clkdev(clk[cspi3_ipg_gate], "ipg", "imx21-cspi.2");
clk_register_clkdev(clk[per3], "per", "imx-fb.0");
clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
clk_register_clkdev(clk[lcdc_hclk_gate], "ahb", "imx-fb.0");
clk_register_clkdev(clk[usb_gate], "per", "imx21-hcd.0");
clk_register_clkdev(clk[usb_hclk_gate], "ahb", "imx21-hcd.0");
clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand.0");
clk_register_clkdev(clk[dma_hclk_gate], "ahb", "imx-dma");
clk_register_clkdev(clk[dma_gate], "ipg", "imx-dma");
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[i2c_gate], NULL, "imx-i2c.0");
clk_register_clkdev(clk[kpp_gate], NULL, "mxc-keypad");
clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
clk_register_clkdev(clk[brom_gate], "brom", NULL);
clk_register_clkdev(clk[emma_gate], "emma", NULL);
clk_register_clkdev(clk[slcdc_gate], "slcdc", NULL);
clk_register_clkdev(clk[gpio_gate], "gpio", NULL);
clk_register_clkdev(clk[rtc_gate], "rtc", NULL);
clk_register_clkdev(clk[csi_hclk_gate], "csi", NULL);
clk_register_clkdev(clk[ssi1_gate], "ssi1", NULL);
clk_register_clkdev(clk[ssi2_gate], "ssi2", NULL);
clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL);
clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL);
mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
MX21_INT_GPT1);
return 0;
}
/*
* Copyright (C) 2009 by Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/mx25.h>
#include "clk.h"
#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
#define CCM_MPCTL 0x00
#define CCM_UPCTL 0x04
#define CCM_CCTL 0x08
#define CCM_CGCR0 0x0C
#define CCM_CGCR1 0x10
#define CCM_CGCR2 0x14
#define CCM_PCDR0 0x18
#define CCM_PCDR1 0x1C
#define CCM_PCDR2 0x20
#define CCM_PCDR3 0x24
#define CCM_RCSR 0x28
#define CCM_CRDR 0x2C
#define CCM_DCVR0 0x30
#define CCM_DCVR1 0x34
#define CCM_DCVR2 0x38
#define CCM_DCVR3 0x3c
#define CCM_LTR0 0x40
#define CCM_LTR1 0x44
#define CCM_LTR2 0x48
#define CCM_LTR3 0x4c
#define CCM_MCR 0x64
#define ccm(x) (CRM_BASE + (x))
static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
static const char *per_sel_clks[] = { "ahb", "upll", };
enum mx25_clks {
dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
csi_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, gpt_ipg_per, i2c_ipg_per,
lcdc_ipg_per, nfc_ipg_per, ssi1_ipg_per, ssi2_ipg_per, uart_ipg_per,
csi_ahb, esdhc1_ahb, esdhc2_ahb, fec_ahb, lcdc_ahb, sdma_ahb,
usbotg_ahb, can1_ipg, can2_ipg, csi_ipg, cspi1_ipg, cspi2_ipg,
cspi3_ipg, dryice_ipg, esdhc1_ipg, esdhc2_ipg, fec_ipg, iim_ipg,
kpp_ipg, lcdc_ipg, pwm1_ipg, pwm2_ipg, pwm3_ipg, pwm4_ipg, sdma_ipg,
ssi1_ipg, ssi2_ipg, tsc_ipg, uart1_ipg, uart2_ipg, uart3_ipg,
uart4_ipg, uart5_ipg, wdt_ipg, clk_max
};
static struct clk *clk[clk_max];
int __init mx25_clocks_init(void)
{
int i;
clk[dummy] = imx_clk_fixed("dummy", 0);
clk[osc] = imx_clk_fixed("osc", 24000000);
clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2);
clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6);
clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6);
clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6);
clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6);
clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6);
clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6);
clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6);
clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6);
clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6);
clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6);
clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6);
clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6);
clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6);
clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6);
clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6);
clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3);
clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4);
clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5);
clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6);
clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0), 7);
clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0), 8);
clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2);
clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3);
clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4);
clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5);
clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6);
clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7);
clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8);
clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0);
clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1);
clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2);
clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6);
clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14);
clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15);
clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
for (i = 0; i < ARRAY_SIZE(clk); i++)
if (IS_ERR(clk[i]))
pr_err("i.MX25 clk %d: register failed with %ld\n",
i, PTR_ERR(clk[i]));
/* i.mx25 has the i.mx21 type uart */
clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
clk_register_clkdev(clk[uart2_ipg], "ipg", "imx21-uart.1");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.1");
clk_register_clkdev(clk[uart3_ipg], "ipg", "imx21-uart.2");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.2");
clk_register_clkdev(clk[uart4_ipg], "ipg", "imx21-uart.3");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.1");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc");
clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
clk_register_clkdev(clk[nfc_ipg_per], NULL, "mxc_nand.0");
/* i.mx25 has the i.mx35 type cspi */
clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1");
clk_register_clkdev(clk[cspi3_ipg], NULL, "imx35-cspi.2");
clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.0");
clk_register_clkdev(clk[per10], "per", "mxc_pwm.0");
clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.1");
clk_register_clkdev(clk[per10], "per", "mxc_pwm.1");
clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.2");
clk_register_clkdev(clk[per10], "per", "mxc_pwm.2");
clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.3");
clk_register_clkdev(clk[per10], "per", "mxc_pwm.3");
clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad");
clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc");
clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.0");
clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.1");
clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.2");
clk_register_clkdev(clk[fec_ipg], "ipg", "imx25-fec.0");
clk_register_clkdev(clk[fec_ahb], "ahb", "imx25-fec.0");
clk_register_clkdev(clk[dryice_ipg], NULL, "imxdi_rtc.0");
clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx-fb.0");
clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");
clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");
clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0");
clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0");
clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1");
clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1");
clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");
clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");
clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0");
clk_register_clkdev(clk[esdhc2_ipg_per], "per", "sdhci-esdhc-imx25.1");
clk_register_clkdev(clk[esdhc2_ipg], "ipg", "sdhci-esdhc-imx25.1");
clk_register_clkdev(clk[esdhc2_ahb], "ahb", "sdhci-esdhc-imx25.1");
clk_register_clkdev(clk[csi_ipg_per], "per", "mx2-camera.0");
clk_register_clkdev(clk[csi_ipg], "ipg", "mx2-camera.0");
clk_register_clkdev(clk[csi_ahb], "ahb", "mx2-camera.0");
clk_register_clkdev(clk[dummy], "audmux", NULL);
clk_register_clkdev(clk[can1_ipg], NULL, "flexcan.0");
clk_register_clkdev(clk[can2_ipg], NULL, "flexcan.1");
/* i.mx25 has the i.mx35 type sdma */
clk_register_clkdev(clk[sdma_ipg], "ipg", "imx35-sdma");
clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
clk_register_clkdev(clk[iim_ipg], "iim", NULL);
mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
return 0;
}
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include "clk.h"
#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
/* Register offsets */
#define CCM_CSCR IO_ADDR_CCM(0x0)
#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
#define CCM_PCDR0 IO_ADDR_CCM(0x18)
#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
#define CCM_PCCR0 IO_ADDR_CCM(0x20)
#define CCM_PCCR1 IO_ADDR_CCM(0x24)
#define CCM_CCSR IO_ADDR_CCM(0x28)
#define CCM_PMCTL IO_ADDR_CCM(0x2c)
#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
#define CCM_CSCR_UPDATE_DIS (1 << 31)
#define CCM_CSCR_SSI2 (1 << 23)
#define CCM_CSCR_SSI1 (1 << 22)
#define CCM_CSCR_VPU (1 << 21)
#define CCM_CSCR_MSHC (1 << 20)
#define CCM_CSCR_SPLLRES (1 << 19)
#define CCM_CSCR_MPLLRES (1 << 18)
#define CCM_CSCR_SP (1 << 17)
#define CCM_CSCR_MCU (1 << 16)
#define CCM_CSCR_OSC26MDIV (1 << 4)
#define CCM_CSCR_OSC26M (1 << 3)
#define CCM_CSCR_FPM (1 << 2)
#define CCM_CSCR_SPEN (1 << 1)
#define CCM_CSCR_MPEN (1 << 0)
/* i.MX27 TO 2+ */
#define CCM_CSCR_ARM_SRC (1 << 15)
#define CCM_SPCTL1_LF (1 << 15)
#define CCM_SPCTL1_BRMO (1 << 6)
static const char *vpu_sel_clks[] = { "spll", "mpll_main2", };
static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
static const char *clko_sel_clks[] = {
"ckil", "prem", "ckih", "ckih",
"ckih", "mpll", "spll", "cpu_div",
"ahb", "ipg", "per1_div", "per2_div",
"per3_div", "per4_div", "ssi1_div", "ssi2_div",
"nfc_div", "mshc_div", "vpu_div", "60m",
"32k", "usb_div", "dptc",
};
static const char *ssi_sel_clks[] = { "spll", "mpll", };
enum mx27_clks {
dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
uart2_ipg_gate, uart1_ipg_gate, clk_max
};
static struct clk *clk[clk_max];
int __init mx27_clocks_init(unsigned long fref)
{
int i;
clk[dummy] = imx_clk_fixed("dummy", 0);
clk[ckih] = imx_clk_fixed("ckih", fref);
clk[ckil] = imx_clk_fixed("ckil", 32768);
clk[mpll] = imx_clk_pllv1("mpll", "ckih", CCM_MPCTL0);
clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2);
clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
} else {
clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4);
clk[ipg] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1);
}
clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4);
clk[per1_div] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6);
clk[per2_div] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6);
clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3);
clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3);
clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2);
else
clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3);
clk[clko_div] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3);
clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3);
clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
clk[slcdc_ipg_gate] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2);
clk[sdhc3_ipg_gate] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3);
clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4);
clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5);
clk[scc_ipg_gate] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6);
clk[sahara_ipg_gate] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7);
clk[rtc_ipg_gate] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9);
clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11);
clk[owire_ipg_gate] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12);
clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14);
clk[kpp_ipg_gate] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15);
clk[iim_ipg_gate] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16);
clk[i2c2_ipg_gate] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17);
clk[i2c1_ipg_gate] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18);
clk[gpt6_ipg_gate] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19);
clk[gpt5_ipg_gate] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20);
clk[gpt4_ipg_gate] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21);
clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22);
clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23);
clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24);
clk[gpio_ipg_gate] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25);
clk[fec_ipg_gate] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26);
clk[emma_ipg_gate] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27);
clk[dma_ipg_gate] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28);
clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29);
clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30);
clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31);
clk[nfc_baud_gate] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3);
clk[ssi2_baud_gate] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4);
clk[ssi1_baud_gate] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5);
clk[vpu_baud_gate] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6);
clk[per4_gate] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7);
clk[per3_gate] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8);
clk[per2_gate] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9);
clk[per1_gate] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10);
clk[usb_ahb_gate] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11);
clk[slcdc_ahb_gate] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12);
clk[sahara_ahb_gate] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13);
clk[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15);
clk[vpu_ahb_gate] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16);
clk[fec_ahb_gate] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17);
clk[emma_ahb_gate] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18);
clk[emi_ahb_gate] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19);
clk[dma_ahb_gate] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20);
clk[csi_ahb_gate] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21);
clk[brom_ahb_gate] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22);
clk[ata_ahb_gate] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23);
clk[wdog_ipg_gate] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24);
clk[usb_ipg_gate] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25);
clk[uart6_ipg_gate] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26);
clk[uart5_ipg_gate] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27);
clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28);
clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29);
clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30);
clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);
for (i = 0; i < ARRAY_SIZE(clk); i++)
if (IS_ERR(clk[i]))
pr_err("i.MX27 clk %d: register failed with %ld\n",
i, PTR_ERR(clk[i]));
clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.0");
clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.1");
clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.2");
clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.3");
clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4");
clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.4");
clk_register_clkdev(clk[uart6_ipg_gate], "ipg", "imx21-uart.5");
clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.5");
clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.0");
clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1");
clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.1");
clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.2");
clk_register_clkdev(clk[gpt4_ipg_gate], "ipg", "imx-gpt.3");
clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.3");
clk_register_clkdev(clk[gpt5_ipg_gate], "ipg", "imx-gpt.4");
clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.4");
clk_register_clkdev(clk[gpt6_ipg_gate], "ipg", "imx-gpt.5");
clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.5");
clk_register_clkdev(clk[pwm_ipg_gate], NULL, "mxc_pwm.0");
clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.0");
clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "mxc-mmc.0");
clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.1");
clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.1");
clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.2");
clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.2");
clk_register_clkdev(clk[cspi1_ipg_gate], NULL, "imx27-cspi.0");
clk_register_clkdev(clk[cspi2_ipg_gate], NULL, "imx27-cspi.1");
clk_register_clkdev(clk[cspi3_ipg_gate], NULL, "imx27-cspi.2");
clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0");
clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0");
clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0");
clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.1");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.1");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0");
clk_register_clkdev(clk[vpu_baud_gate], "per", "imx-vpu");
clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "imx-vpu");
clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx-dma");
clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx-dma");
clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0");
clk_register_clkdev(clk[fec_ahb_gate], "ahb", "imx27-fec.0");
clk_register_clkdev(clk[wdog_ipg_gate], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[i2c1_ipg_gate], NULL, "imx-i2c.0");
clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1");
clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0");
clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad");
clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma");
clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma");
clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL);
clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL);
clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL);
clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
clk_register_clkdev(clk[rtc_ipg_gate], "rtc", NULL);
clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
clk_register_clkdev(clk[cpu_div], "cpu", NULL);
clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0");
clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1");
mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
MX27_INT_GPT1);
clk_prepare_enable(clk[emi_ahb_gate]);
return 0;
}
#ifdef CONFIG_OF
int __init mx27_clocks_init_dt(void)
{
struct device_node *np;
u32 fref = 26000000; /* default */
for_each_compatible_node(np, NULL, "fixed-clock") {
if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
continue;
if (!of_property_read_u32(np, "clock-frequency", &fref))
break;
}
return mx27_clocks_init(fref);
}
#endif
/*
* Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation.
*/
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/mx31.h>
#include <mach/common.h>
#include "clk.h"
#include "crmregs-imx3.h"
static const char *mcu_main_sel[] = { "spll", "mpll", };
static const char *per_sel[] = { "per_div", "ipg", };
static const char *csi_sel[] = { "upll", "spll", };
static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
enum mx31_clks {
ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
};
static struct clk *clk[clk_max];
int __init mx31_clocks_init(unsigned long fref)
{
void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
int i;
clk[ckih] = imx_clk_fixed("ckih", fref);
clk[ckil] = imx_clk_fixed("ckil", 32768);
clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel));
clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3);
clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6);
clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12);
for (i = 0; i < ARRAY_SIZE(clk); i++)
if (IS_ERR(clk[i]))
pr_err("imx31 clk %d: register failed with %ld\n",
i, PTR_ERR(clk[i]));
clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1");
clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[rtc_gate], "rtc", NULL);
clk_register_clkdev(clk[epit1_gate], "epit", NULL);
clk_register_clkdev(clk[epit2_gate], "epit", NULL);
clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0");
clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
clk_register_clkdev(clk[kpp_gate], "kpp", NULL);
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1");
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc");
clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc");
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
/* i.mx31 has the i.mx21 type uart */
clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
clk_register_clkdev(clk[sdhc1_gate], NULL, "mxc-mmc.0");
clk_register_clkdev(clk[sdhc2_gate], NULL, "mxc-mmc.1");
clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
clk_register_clkdev(clk[firi_gate], "firi", NULL);
clk_register_clkdev(clk[ata_gate], NULL, "pata_imx");
clk_register_clkdev(clk[rtic_gate], "rtic", NULL);
clk_register_clkdev(clk[rng_gate], "rng", NULL);
clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
clk_register_clkdev(clk[iim_gate], "iim", NULL);
clk_set_parent(clk[csi], clk[upll]);
clk_prepare_enable(clk[emi_gate]);
clk_prepare_enable(clk[iim_gate]);
mx31_revision();
clk_disable_unprepare(clk[iim_gate]);
mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
MX31_INT_GPT);
return 0;
}
/*
* Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include "crmregs-imx3.h"
#include "clk.h"
struct arm_ahb_div {
unsigned char arm, ahb, sel;
};
static struct arm_ahb_div clk_consumer[] = {
{ .arm = 1, .ahb = 4, .sel = 0},
{ .arm = 1, .ahb = 3, .sel = 1},
{ .arm = 2, .ahb = 2, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
{ .arm = 4, .ahb = 1, .sel = 0},
{ .arm = 1, .ahb = 5, .sel = 0},
{ .arm = 1, .ahb = 8, .sel = 0},
{ .arm = 1, .ahb = 6, .sel = 1},
{ .arm = 2, .ahb = 4, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
{ .arm = 4, .ahb = 2, .sel = 0},
{ .arm = 0, .ahb = 0, .sel = 0},
};
static char hsp_div_532[] = { 4, 8, 3, 0 };
static char hsp_div_400[] = { 3, 6, 3, 0 };
static const char *std_sel[] = {"ppll", "arm"};
static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
enum mx35_clks {
ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
clk_max
};
static struct clk *clk[clk_max];
int __init mx35_clocks_init()
{
void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
u32 pdr0, consumer_sel, hsp_sel;
struct arm_ahb_div *aad;
unsigned char *hsp_div;
int i;
pdr0 = __raw_readl(base + MXC_CCM_PDR0);
consumer_sel = (pdr0 >> 16) & 0xf;
aad = &clk_consumer[consumer_sel];
if (!aad->arm) {
pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
/*
* We are basically stuck. Continue with a default entry and hope we
* get far enough to actually show the above message
*/
aad = &clk_consumer[0];
}
clk[ckih] = imx_clk_fixed("ckih", 24000000);
clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL);
clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL);
clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
if (aad->sel)
clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
else
clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
if (clk_get_rate(clk[arm]) > 400000000)
hsp_div = hsp_div_532;
else
hsp_div = hsp_div_400;
hsp_sel = (pdr0 >> 20) & 0x3;
if (!hsp_div[hsp_sel]) {
pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
hsp_sel = 0;
}
clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6);
clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3);
clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6);
clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6);
clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6);
clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3);
clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6);
clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3);
clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6);
clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6);
clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0);
clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2);
clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4);
clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6);
clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8);
clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10);
clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12);
clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14);
clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16);
clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18);
clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20);
clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22);
clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24);
clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26);
clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28);
clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30);
clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0);
clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2);
clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4);
clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6);
clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8);
clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10);
clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12);
clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14);
clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16);
clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18);
clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20);
clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22);
clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24);
clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26);
clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28);
clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30);
clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0);
clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2);
clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4);
clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6);
clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8);
clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10);
clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12);
clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14);
clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16);
clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18);
clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20);
clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22);
clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24);
clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30);
clk[csi_gate] = imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3, 0);
clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2);
clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4);
for (i = 0; i < ARRAY_SIZE(clk); i++)
if (IS_ERR(clk[i]))
pr_err("i.MX35 clk %d: register failed with %ld\n",
i, PTR_ERR(clk[i]));
clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0");
clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0");
clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1");
clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1");
clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0");
clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1");
clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0");
clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0");
clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0");
clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1");
clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1");
clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1");
clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2");
clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2");
clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2");
/* i.mx35 has the i.mx27 type fec */
clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0");
clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0");
clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1");
clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1");
/* i.mx35 has the i.mx21 type uart */
clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0");
clk_prepare_enable(clk[spba_gate]);
clk_prepare_enable(clk[gpio1_gate]);
clk_prepare_enable(clk[gpio2_gate]);
clk_prepare_enable(clk[gpio3_gate]);
clk_prepare_enable(clk[iim_gate]);
clk_prepare_enable(clk[emi_gate]);
imx_print_silicon_rev("i.MX35", mx35_revision());
#ifdef CONFIG_MXC_USE_EPIT
epit_timer_init(&epit1_clk,
MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
#else
mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR),
MX35_INT_GPT);
#endif
return 0;
}
此差异已折叠。
此差异已折叠。
/*
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include "clk.h"
/**
* struct clk_pfd - IMX PFD clock
* @clk_hw: clock source
* @reg: PFD register address
* @idx: the index of PFD encoded in the register
*
* PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
* data encoded, and member idx is used to specify the one. And each
* register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
*/
struct clk_pfd {
struct clk_hw hw;
void __iomem *reg;
u8 idx;
};
#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
#define SET 0x4
#define CLR 0x8
#define OTG 0xc
static int clk_pfd_enable(struct clk_hw *hw)
{
struct clk_pfd *pfd = to_clk_pfd(hw);
writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
return 0;
}
static void clk_pfd_disable(struct clk_hw *hw)
{
struct clk_pfd *pfd = to_clk_pfd(hw);
writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
}
static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pfd *pfd = to_clk_pfd(hw);
u64 tmp = parent_rate;
u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
tmp *= 18;
do_div(tmp, frac);
return tmp;
}
static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
u64 tmp = *prate;
u8 frac;
tmp = tmp * 18 + rate / 2;
do_div(tmp, rate);
frac = tmp;
if (frac < 12)
frac = 12;
else if (frac > 35)
frac = 35;
tmp = *prate;
tmp *= 18;
do_div(tmp, frac);
return tmp;
}
static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pfd *pfd = to_clk_pfd(hw);
u64 tmp = parent_rate;
u8 frac;
tmp = tmp * 18 + rate / 2;
do_div(tmp, rate);
frac = tmp;
if (frac < 12)
frac = 12;
else if (frac > 35)
frac = 35;
writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR);
writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET);
return 0;
}
static const struct clk_ops clk_pfd_ops = {
.enable = clk_pfd_enable,
.disable = clk_pfd_disable,
.recalc_rate = clk_pfd_recalc_rate,
.round_rate = clk_pfd_round_rate,
.set_rate = clk_pfd_set_rate,
};
struct clk *imx_clk_pfd(const char *name, const char *parent_name,
void __iomem *reg, u8 idx)
{
struct clk_pfd *pfd;
struct clk *clk;
struct clk_init_data init;
pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
if (!pfd)
return ERR_PTR(-ENOMEM);
pfd->reg = reg;
pfd->idx = idx;
init.name = name;
init.ops = &clk_pfd_ops;
init.flags = 0;
init.parent_names = &parent_name;
init.num_parents = 1;
pfd->hw.init = &init;
clk = clk_register(NULL, &pfd->hw);
if (IS_ERR(clk))
kfree(pfd);
return clk;
}
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/clock.h>
#include "clk.h"
/**
* pll v1
*
* @clk_hw clock source
* @parent the parent clock name
* @base base address of pll registers
*
* PLL clock version 1, found on i.MX1/21/25/27/31/35
*/
struct clk_pllv1 {
struct clk_hw hw;
void __iomem *base;
};
#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv1 *pll = to_clk_pllv1(hw);
return mxc_decode_pll(readl(pll->base), parent_rate);
}
struct clk_ops clk_pllv1_ops = {
.recalc_rate = clk_pllv1_recalc_rate,
};
struct clk *imx_clk_pllv1(const char *name, const char *parent,
void __iomem *base)
{
struct clk_pllv1 *pll;
struct clk *clk;
struct clk_init_data init;
pll = kmalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
pll->base = base;
init.name = name;
init.ops = &clk_pllv1_ops;
init.flags = 0;
init.parent_names = &parent;
init.num_parents = 1;
pll->hw.init = &init;
clk = clk_register(NULL, &pll->hw);
if (IS_ERR(clk))
kfree(pll);
return clk;
}
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <asm/div64.h>
#include "clk.h"
#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk))
/* PLL Register Offsets */
#define MXC_PLL_DP_CTL 0x00
#define MXC_PLL_DP_CONFIG 0x04
#define MXC_PLL_DP_OP 0x08
#define MXC_PLL_DP_MFD 0x0C
#define MXC_PLL_DP_MFN 0x10
#define MXC_PLL_DP_MFNMINUS 0x14
#define MXC_PLL_DP_MFNPLUS 0x18
#define MXC_PLL_DP_HFS_OP 0x1C
#define MXC_PLL_DP_HFS_MFD 0x20
#define MXC_PLL_DP_HFS_MFN 0x24
#define MXC_PLL_DP_MFN_TOGC 0x28
#define MXC_PLL_DP_DESTAT 0x2c
/* PLL Register Bit definitions */
#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
#define MXC_PLL_DP_CTL_ADE 0x800
#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
#define MXC_PLL_DP_CTL_HFSM 0x80
#define MXC_PLL_DP_CTL_PRE 0x40
#define MXC_PLL_DP_CTL_UPEN 0x20
#define MXC_PLL_DP_CTL_RST 0x10
#define MXC_PLL_DP_CTL_RCP 0x8
#define MXC_PLL_DP_CTL_PLM 0x4
#define MXC_PLL_DP_CTL_BRM0 0x2
#define MXC_PLL_DP_CTL_LRF 0x1
#define MXC_PLL_DP_CONFIG_BIST 0x8
#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
#define MXC_PLL_DP_CONFIG_AREN 0x2
#define MXC_PLL_DP_CONFIG_LDREQ 0x1
#define MXC_PLL_DP_OP_MFI_OFFSET 4
#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
#define MXC_PLL_DP_OP_PDF_OFFSET 0
#define MXC_PLL_DP_OP_PDF_MASK 0xF
#define MXC_PLL_DP_MFD_OFFSET 0
#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
#define MXC_PLL_DP_MFN_OFFSET 0x0
#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
struct clk_pllv2 {
struct clk_hw hw;
void __iomem *base;
};
static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
void __iomem *pllbase;
s64 temp;
struct clk_pllv2 *pll = to_clk_pllv2(hw);
pllbase = pll->base;
dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
if (pll_hfsm == 0) {
dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
} else {
dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
}
pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
mfi = (mfi <= 5) ? 5 : mfi;
mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
/* Sign extend to 32-bits */
if (mfn >= 0x04000000) {
mfn |= 0xFC000000;
mfn_abs = -mfn;
}
ref_clk = 2 * parent_rate;
if (dbl != 0)
ref_clk *= 2;
ref_clk /= (pdf + 1);
temp = (u64) ref_clk * mfn_abs;
do_div(temp, mfd + 1);
if (mfn < 0)
temp = -temp;
temp = (ref_clk * mfi) + temp;
return temp;
}
static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv2 *pll = to_clk_pllv2(hw);
u32 reg;
void __iomem *pllbase;
long mfi, pdf, mfn, mfd = 999999;
s64 temp64;
unsigned long quad_parent_rate;
unsigned long pll_hfsm, dp_ctl;
pllbase = pll->base;
quad_parent_rate = 4 * parent_rate;
pdf = mfi = -1;
while (++pdf < 16 && mfi < 5)
mfi = rate * (pdf+1) / quad_parent_rate;
if (mfi > 15)
return -EINVAL;
pdf--;
temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
do_div(temp64, quad_parent_rate/1000000);
mfn = (long)temp64;
dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
/* use dpdck0_2 */
__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
if (pll_hfsm == 0) {
reg = mfi << 4 | pdf;
__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
} else {
reg = mfi << 4 | pdf;
__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
}
return 0;
}
static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
return rate;
}
static int clk_pllv2_prepare(struct clk_hw *hw)
{
struct clk_pllv2 *pll = to_clk_pllv2(hw);
u32 reg;
void __iomem *pllbase;
int i = 0;
pllbase = pll->base;
reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
/* Wait for lock */
do {
reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
if (reg & MXC_PLL_DP_CTL_LRF)
break;
udelay(1);
} while (++i < MAX_DPLL_WAIT_TRIES);
if (i == MAX_DPLL_WAIT_TRIES) {
pr_err("MX5: pll locking failed\n");
return -EINVAL;
}
return 0;
}
static void clk_pllv2_unprepare(struct clk_hw *hw)
{
struct clk_pllv2 *pll = to_clk_pllv2(hw);
u32 reg;
void __iomem *pllbase;
pllbase = pll->base;
reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
}
struct clk_ops clk_pllv2_ops = {
.prepare = clk_pllv2_prepare,
.unprepare = clk_pllv2_unprepare,
.recalc_rate = clk_pllv2_recalc_rate,
.round_rate = clk_pllv2_round_rate,
.set_rate = clk_pllv2_set_rate,
};
struct clk *imx_clk_pllv2(const char *name, const char *parent,
void __iomem *base)
{
struct clk_pllv2 *pll;
struct clk *clk;
struct clk_init_data init;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
pll->base = base;
init.name = name;
init.ops = &clk_pllv2_ops;
init.flags = 0;
init.parent_names = &parent;
init.num_parents = 1;
pll->hw.init = &init;
clk = clk_register(NULL, &pll->hw);
if (IS_ERR(clk))
kfree(pll);
return clk;
}
/*
* Copyright 2012 Freescale Semiconductor, Inc.
* Copyright 2012 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/err.h>
#include "clk.h"
#define PLL_NUM_OFFSET 0x10
#define PLL_DENOM_OFFSET 0x20
#define BM_PLL_POWER (0x1 << 12)
#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_BYPASS (0x1 << 16)
#define BM_PLL_LOCK (0x1 << 31)
/**
* struct clk_pllv3 - IMX PLL clock version 3
* @clk_hw: clock source
* @base: base address of PLL registers
* @powerup_set: set POWER bit to power up the PLL
* @gate_mask: mask of gate bits
* @div_mask: mask of divider bits
*
* IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
* is actually a multiplier, and always sits at bit 0.
*/
struct clk_pllv3 {
struct clk_hw hw;
void __iomem *base;
bool powerup_set;
u32 gate_mask;
u32 div_mask;
};
#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
static int clk_pllv3_prepare(struct clk_hw *hw)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
unsigned long timeout = jiffies + msecs_to_jiffies(10);
u32 val;
val = readl_relaxed(pll->base);
val &= ~BM_PLL_BYPASS;
if (pll->powerup_set)
val |= BM_PLL_POWER;
else
val &= ~BM_PLL_POWER;
writel_relaxed(val, pll->base);
/* Wait for PLL to lock */
while (!(readl_relaxed(pll->base) & BM_PLL_LOCK))
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
return 0;
}
static void clk_pllv3_unprepare(struct clk_hw *hw)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 val;
val = readl_relaxed(pll->base);
val |= BM_PLL_BYPASS;
if (pll->powerup_set)
val &= ~BM_PLL_POWER;
else
val |= BM_PLL_POWER;
writel_relaxed(val, pll->base);
}
static int clk_pllv3_enable(struct clk_hw *hw)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 val;
val = readl_relaxed(pll->base);
val |= pll->gate_mask;
writel_relaxed(val, pll->base);
return 0;
}
static void clk_pllv3_disable(struct clk_hw *hw)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 val;
val = readl_relaxed(pll->base);
val &= ~pll->gate_mask;
writel_relaxed(val, pll->base);
}
static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 div = readl_relaxed(pll->base) & pll->div_mask;
return (div == 1) ? parent_rate * 22 : parent_rate * 20;
}
static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
return (rate >= parent_rate * 22) ? parent_rate * 22 :
parent_rate * 20;
}
static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 val, div;
if (rate == parent_rate * 22)
div = 1;
else if (rate == parent_rate * 20)
div = 0;
else
return -EINVAL;
val = readl_relaxed(pll->base);
val &= ~pll->div_mask;
val |= div;
writel_relaxed(val, pll->base);
return 0;
}
static const struct clk_ops clk_pllv3_ops = {
.prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare,
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
.recalc_rate = clk_pllv3_recalc_rate,
.round_rate = clk_pllv3_round_rate,
.set_rate = clk_pllv3_set_rate,
};
static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 div = readl_relaxed(pll->base) & pll->div_mask;
return parent_rate * div / 2;
}
static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
unsigned long min_rate = parent_rate * 54 / 2;
unsigned long max_rate = parent_rate * 108 / 2;
u32 div;
if (rate > max_rate)
rate = max_rate;
else if (rate < min_rate)
rate = min_rate;
div = rate * 2 / parent_rate;
return parent_rate * div / 2;
}
static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
unsigned long min_rate = parent_rate * 54 / 2;
unsigned long max_rate = parent_rate * 108 / 2;
u32 val, div;
if (rate < min_rate || rate > max_rate)
return -EINVAL;
div = rate * 2 / parent_rate;
val = readl_relaxed(pll->base);
val &= ~pll->div_mask;
val |= div;
writel_relaxed(val, pll->base);
return 0;
}
static const struct clk_ops clk_pllv3_sys_ops = {
.prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare,
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
.recalc_rate = clk_pllv3_sys_recalc_rate,
.round_rate = clk_pllv3_sys_round_rate,
.set_rate = clk_pllv3_sys_set_rate,
};
static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
u32 div = readl_relaxed(pll->base) & pll->div_mask;
return (parent_rate * div) + ((parent_rate / mfd) * mfn);
}
static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
unsigned long min_rate = parent_rate * 27;
unsigned long max_rate = parent_rate * 54;
u32 div;
u32 mfn, mfd = 1000000;
s64 temp64;
if (rate > max_rate)
rate = max_rate;
else if (rate < min_rate)
rate = min_rate;
div = rate / parent_rate;
temp64 = (u64) (rate - div * parent_rate);
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
return parent_rate * div + parent_rate / mfd * mfn;
}
static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
unsigned long min_rate = parent_rate * 27;
unsigned long max_rate = parent_rate * 54;
u32 val, div;
u32 mfn, mfd = 1000000;
s64 temp64;
if (rate < min_rate || rate > max_rate)
return -EINVAL;
div = rate / parent_rate;
temp64 = (u64) (rate - div * parent_rate);
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
val = readl_relaxed(pll->base);
val &= ~pll->div_mask;
val |= div;
writel_relaxed(val, pll->base);
writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
return 0;
}
static const struct clk_ops clk_pllv3_av_ops = {
.prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare,
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
.recalc_rate = clk_pllv3_av_recalc_rate,
.round_rate = clk_pllv3_av_round_rate,
.set_rate = clk_pllv3_av_set_rate,
};
static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 div = readl_relaxed(pll->base) & pll->div_mask;
switch (div) {
case 0:
return 25000000;
case 1:
return 50000000;
case 2:
return 100000000;
case 3:
return 125000000;
}
return 0;
}
static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
if (rate >= 125000000)
rate = 125000000;
else if (rate >= 100000000)
rate = 100000000;
else if (rate >= 50000000)
rate = 50000000;
else
rate = 25000000;
return rate;
}
static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
u32 val, div;
switch (rate) {
case 25000000:
div = 0;
break;
case 50000000:
div = 1;
break;
case 100000000:
div = 2;
break;
case 125000000:
div = 3;
break;
default:
return -EINVAL;
}
val = readl_relaxed(pll->base);
val &= ~pll->div_mask;
val |= div;
writel_relaxed(val, pll->base);
return 0;
}
static const struct clk_ops clk_pllv3_enet_ops = {
.prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare,
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
.recalc_rate = clk_pllv3_enet_recalc_rate,
.round_rate = clk_pllv3_enet_round_rate,
.set_rate = clk_pllv3_enet_set_rate,
};
static const struct clk_ops clk_pllv3_mlb_ops = {
.prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare,
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
};
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent_name, void __iomem *base,
u32 gate_mask, u32 div_mask)
{
struct clk_pllv3 *pll;
const struct clk_ops *ops;
struct clk *clk;
struct clk_init_data init;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
switch (type) {
case IMX_PLLV3_SYS:
ops = &clk_pllv3_sys_ops;
break;
case IMX_PLLV3_USB:
ops = &clk_pllv3_ops;
pll->powerup_set = true;
break;
case IMX_PLLV3_AV:
ops = &clk_pllv3_av_ops;
break;
case IMX_PLLV3_ENET:
ops = &clk_pllv3_enet_ops;
break;
case IMX_PLLV3_MLB:
ops = &clk_pllv3_mlb_ops;
break;
default:
ops = &clk_pllv3_ops;
}
pll->base = base;
pll->gate_mask = gate_mask;
pll->div_mask = div_mask;
init.name = name;
init.ops = ops;
init.flags = 0;
init.parent_names = &parent_name;
init.num_parents = 1;
pll->hw.init = &init;
clk = clk_register(NULL, &pll->hw);
if (IS_ERR(clk))
kfree(pll);
return clk;
}
#ifndef __MACH_IMX_CLK_H
#define __MACH_IMX_CLK_H
#include <linux/spinlock.h>
#include <linux/clk-provider.h>
#include <mach/clock.h>
struct clk *imx_clk_pllv1(const char *name, const char *parent,
void __iomem *base);
struct clk *imx_clk_pllv2(const char *name, const char *parent,
void __iomem *base);
enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
IMX_PLLV3_SYS,
IMX_PLLV3_USB,
IMX_PLLV3_AV,
IMX_PLLV3_ENET,
IMX_PLLV3_MLB,
};
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent_name, void __iomem *base, u32 gate_mask,
u32 div_mask);
struct clk *clk_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock);
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
shift, 0, &imx_ccm_lock);
}
struct clk *imx_clk_pfd(const char *name, const char *parent_name,
void __iomem *reg, u8 idx);
struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
void __iomem *reg, u8 shift, u8 width,
void __iomem *busy_reg, u8 busy_shift);
struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
u8 width, void __iomem *busy_reg, u8 busy_shift,
const char **parent_names, int num_parents);
static inline struct clk *imx_clk_fixed(const char *name, int rate)
{
return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
}
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width)
{
return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
reg, shift, width, 0, &imx_ccm_lock);
}
static inline struct clk *imx_clk_gate(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
shift, 0, &imx_ccm_lock);
}
static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, int num_parents)
{
return clk_register_mux(NULL, name, parents, num_parents, 0, reg, shift,
width, 0, &imx_ccm_lock);
}
static inline struct clk *imx_clk_fixed_factor(const char *name,
const char *parent, unsigned int mult, unsigned int div)
{
return clk_register_fixed_factor(NULL, name, parent,
CLK_SET_RATE_PARENT, mult, div);
}
#endif
此差异已折叠。
此差异已折叠。
/*
* Copyright (C) 2009 by Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/mx25.h>
#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
#define CCM_MPCTL 0x00
#define CCM_UPCTL 0x04
#define CCM_CCTL 0x08
#define CCM_CGCR0 0x0C
#define CCM_CGCR1 0x10
#define CCM_CGCR2 0x14
#define CCM_PCDR0 0x18
#define CCM_PCDR1 0x1C
#define CCM_PCDR2 0x20
#define CCM_PCDR3 0x24
#define CCM_RCSR 0x28
#define CCM_CRDR 0x2C
#define CCM_DCVR0 0x30
#define CCM_DCVR1 0x34
#define CCM_DCVR2 0x38
#define CCM_DCVR3 0x3c
#define CCM_LTR0 0x40
#define CCM_LTR1 0x44
#define CCM_LTR2 0x48
#define CCM_LTR3 0x4c
static unsigned long get_rate_mpll(void)
{
ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
return mxc_decode_pll(mpctl, 24000000);
}
static unsigned long get_rate_upll(void)
{
ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
return mxc_decode_pll(mpctl, 24000000);
}
unsigned long get_rate_arm(struct clk *clk)
{
unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
unsigned long rate = get_rate_mpll();
if (cctl & (1 << 14))
rate = (rate * 3) >> 2;
return rate / ((cctl >> 30) + 1);
}
static unsigned long get_rate_ahb(struct clk *clk)
{
unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
}
static unsigned long get_rate_ipg(struct clk *clk)
{
return get_rate_ahb(NULL) >> 1;
}
static unsigned long get_rate_per(int per)
{
unsigned long ofs = (per & 0x3) * 8;
unsigned long reg = per & ~0x3;
unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
unsigned long fref;
if (readl(CRM_BASE + 0x64) & (1 << per))
fref = get_rate_upll();
else
fref = get_rate_ahb(NULL);
return fref / (val + 1);
}
static unsigned long get_rate_uart(struct clk *clk)
{
return get_rate_per(15);
}
static unsigned long get_rate_ssi2(struct clk *clk)
{
return get_rate_per(14);
}
static unsigned long get_rate_ssi1(struct clk *clk)
{
return get_rate_per(13);
}
static unsigned long get_rate_i2c(struct clk *clk)
{
return get_rate_per(6);
}
static unsigned long get_rate_nfc(struct clk *clk)
{
return get_rate_per(8);
}
static unsigned long get_rate_gpt(struct clk *clk)
{
return get_rate_per(5);
}
static unsigned long get_rate_lcdc(struct clk *clk)
{
return get_rate_per(7);
}
static unsigned long get_rate_esdhc1(struct clk *clk)
{
return get_rate_per(3);
}
static unsigned long get_rate_esdhc2(struct clk *clk)
{
return get_rate_per(4);
}
static unsigned long get_rate_csi(struct clk *clk)
{
return get_rate_per(0);
}
static unsigned long get_rate_otg(struct clk *clk)
{
unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
unsigned long rate = get_rate_upll();
return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
}
static int clk_cgcr_enable(struct clk *clk)
{
u32 reg;
reg = __raw_readl(clk->enable_reg);
reg |= 1 << clk->enable_shift;
__raw_writel(reg, clk->enable_reg);
return 0;
}
static void clk_cgcr_disable(struct clk *clk)
{
u32 reg;
reg = __raw_readl(clk->enable_reg);
reg &= ~(1 << clk->enable_shift);
__raw_writel(reg, clk->enable_reg);
}
#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
static struct clk name = { \
.id = i, \
.enable_reg = CRM_BASE + er, \
.enable_shift = es, \
.get_rate = gr, \
.set_rate = sr, \
.enable = clk_cgcr_enable, \
.disable = clk_cgcr_disable, \
.secondary = s, \
}
/*
* Note: the following IPG clock gating bits are wrongly marked "Reserved" in
* the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
* taken from the Freescale released BSP.
*
* bit reg offset clock
*
* 0 CGCR1 0 AUDMUX
* 12 CGCR1 12 ESAI
* 16 CGCR1 16 GPIO1
* 17 CGCR1 17 GPIO2
* 18 CGCR1 18 GPIO3
* 23 CGCR1 23 I2C1
* 24 CGCR1 24 I2C2
* 25 CGCR1 25 I2C3
* 27 CGCR1 27 IOMUXC
* 28 CGCR1 28 KPP
* 30 CGCR1 30 OWIRE
* 36 CGCR2 4 RTIC
* 51 CGCR2 19 WDOG
*/
DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
&esdhc1_ahb_clk);
DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
&esdhc2_ahb_clk);
DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL);
DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL);
DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk);
DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
&esdhc1_per_clk);
DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
&esdhc2_per_clk);
DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(iim_clk, 0, CCM_CGCR1, 26, NULL, NULL, NULL);
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
.con_id = n, \
.clk = &c, \
},
static struct clk_lookup lookups[] = {
/* i.mx25 has the i.mx21 type uart */
_REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
_REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
_REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
_REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
_REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
_REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
/* i.mx25 has the i.mx35 type cspi */
_REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
_REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
_REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk)
_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
_REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
_REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
_REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
_REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
_REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
_REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
_REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
_REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk)
_REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk)
_REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
/* i.mx25 has the i.mx35 type sdma */
_REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
_REGISTER_CLOCK(NULL, "iim", iim_clk)
};
int __init mx25_clocks_init(void)
{
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
/* Turn off all clocks except the ones we need to survive, namely:
* EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
* SCC
*/
__raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
__raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
__raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
clk_enable(&uart1_clk);
#endif
/* Clock source for lcdc and csi is upll */
__raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
CRM_BASE + 0x64);
/* Clock source for gpt is ahb_div */
__raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64);
clk_enable(&iim_clk);
imx_print_silicon_rev("i.MX25", mx25_revision());
clk_disable(&iim_clk);
mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
return 0;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -17,6 +17,12 @@ ...@@ -17,6 +17,12 @@
#include <mach/hardware.h> #include <mach/hardware.h>
static struct map_desc imx_lluart_desc = { static struct map_desc imx_lluart_desc = {
#ifdef CONFIG_DEBUG_IMX6Q_UART2
.virtual = MX6Q_IO_P2V(MX6Q_UART2_BASE_ADDR),
.pfn = __phys_to_pfn(MX6Q_UART2_BASE_ADDR),
.length = MX6Q_UART2_SIZE,
.type = MT_DEVICE,
#endif
#ifdef CONFIG_DEBUG_IMX6Q_UART4 #ifdef CONFIG_DEBUG_IMX6Q_UART4
.virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR), .virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
.pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR), .pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
......
此差异已折叠。
此差异已折叠。
...@@ -33,6 +33,7 @@ static void imx5_idle(void) ...@@ -33,6 +33,7 @@ static void imx5_idle(void)
gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
if (IS_ERR(gpc_dvfs_clk)) if (IS_ERR(gpc_dvfs_clk))
return; return;
clk_prepare(gpc_dvfs_clk);
} }
clk_enable(gpc_dvfs_clk); clk_enable(gpc_dvfs_clk);
mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册