mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-03-07 12:12:07 +00:00
Merge branch 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt2
* 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6: (51 commits) ARM: dts: enable audio support for imx28-evk ARM: dts: enable i2c device for imx28-evk i2c: mxs: add device tree probe support ARM: dts: enable mmc for imx28-evk ARM: dts: enable mmc for imx23-evk mmc: mxs-mmc: add device tree support mmc: mxs-mmc: copy wp_gpio in struct mxs_mmc_host mmc: mxs-mmc: have dma_channel than dma_res in mxs_mmc_host mmc: mxs-mmc: use devm_* helper to make cleanup simpler mmc: mxs-mmc: move header from mach into linux folder mmc: mxs-mmc: get rid of the use of cpu_is_xxx mmc: mxs-mmc: let ssp_is_old take host as parameter mmc: mxs-mmc: use global stmp_device functionality ARM: mxs: add gpio support for device tree boot gpio/mxs: add device tree probe gpio/mxs: get rid of the use of cpu_is_xxx gpio/mxs: use devm_* helpers to make error handling simple ARM: mxs: add mxs-dma dt support ARM: mxs: do not add dma device by default dma: mxs-dma: add device tree probe support ...
This commit is contained in:
commit
e29402edf8
@ -1,6 +1,14 @@
|
||||
Freescale i.MX Platforms Device Tree Bindings
|
||||
-----------------------------------------------
|
||||
|
||||
i.MX23 Evaluation Kit
|
||||
Required root node properties:
|
||||
- compatible = "fsl,imx23-evk", "fsl,imx23";
|
||||
|
||||
i.MX28 Evaluation Kit
|
||||
Required root node properties:
|
||||
- compatible = "fsl,imx28-evk", "fsl,imx28";
|
||||
|
||||
i.MX51 Babbage Board
|
||||
Required root node properties:
|
||||
- compatible = "fsl,imx51-babbage", "fsl,imx51";
|
||||
|
19
Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt
Normal file
19
Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt
Normal file
@ -0,0 +1,19 @@
|
||||
* Freescale MXS DMA
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "fsl,<chip>-dma-apbh" or "fsl,<chip>-dma-apbx"
|
||||
- reg : Should contain registers location and length
|
||||
|
||||
Supported chips:
|
||||
imx23, imx28.
|
||||
|
||||
Examples:
|
||||
dma-apbh@80004000 {
|
||||
compatible = "fsl,imx28-dma-apbh";
|
||||
reg = <0x80004000 2000>;
|
||||
};
|
||||
|
||||
dma-apbx@80024000 {
|
||||
compatible = "fsl,imx28-dma-apbx";
|
||||
reg = <0x80024000 2000>;
|
||||
};
|
87
Documentation/devicetree/bindings/gpio/gpio-mxs.txt
Normal file
87
Documentation/devicetree/bindings/gpio/gpio-mxs.txt
Normal file
@ -0,0 +1,87 @@
|
||||
* Freescale MXS GPIO controller
|
||||
|
||||
The Freescale MXS GPIO controller is part of MXS PIN controller. The
|
||||
GPIOs are organized in port/bank. Each port consists of 32 GPIOs.
|
||||
|
||||
As the GPIO controller is embedded in the PIN controller and all the
|
||||
GPIO ports share the same IO space with PIN controller, the GPIO node
|
||||
will be represented as sub-nodes of MXS pinctrl node.
|
||||
|
||||
Required properties for GPIO node:
|
||||
- compatible : Should be "fsl,<soc>-gpio". The supported SoCs include
|
||||
imx23 and imx28.
|
||||
- interrupts : Should be the port interrupt shared by all 32 pins.
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify optional parameters (currently
|
||||
unused).
|
||||
- interrupt-controller: Marks the device node as an interrupt controller.
|
||||
- #interrupt-cells : Should be 2. The first cell is the GPIO number.
|
||||
The second cell bits[3:0] is used to specify trigger type and level flags:
|
||||
1 = low-to-high edge triggered.
|
||||
2 = high-to-low edge triggered.
|
||||
4 = active high level-sensitive.
|
||||
8 = active low level-sensitive.
|
||||
|
||||
Note: Each GPIO port should have an alias correctly numbered in "aliases"
|
||||
node.
|
||||
|
||||
Examples:
|
||||
|
||||
aliases {
|
||||
gpio0 = &gpio0;
|
||||
gpio1 = &gpio1;
|
||||
gpio2 = &gpio2;
|
||||
gpio3 = &gpio3;
|
||||
gpio4 = &gpio4;
|
||||
};
|
||||
|
||||
pinctrl@80018000 {
|
||||
compatible = "fsl,imx28-pinctrl", "simple-bus";
|
||||
reg = <0x80018000 2000>;
|
||||
|
||||
gpio0: gpio@0 {
|
||||
compatible = "fsl,imx28-gpio";
|
||||
interrupts = <127>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio1: gpio@1 {
|
||||
compatible = "fsl,imx28-gpio";
|
||||
interrupts = <126>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio2: gpio@2 {
|
||||
compatible = "fsl,imx28-gpio";
|
||||
interrupts = <125>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio3: gpio@3 {
|
||||
compatible = "fsl,imx28-gpio";
|
||||
interrupts = <124>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio4: gpio@4 {
|
||||
compatible = "fsl,imx28-gpio";
|
||||
interrupts = <123>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
};
|
16
Documentation/devicetree/bindings/i2c/i2c-mxs.txt
Normal file
16
Documentation/devicetree/bindings/i2c/i2c-mxs.txt
Normal file
@ -0,0 +1,16 @@
|
||||
* Freescale MXS Inter IC (I2C) Controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,<chip>-i2c"
|
||||
- reg: Should contain registers location and length
|
||||
- interrupts: Should contain ERROR and DMA interrupts
|
||||
|
||||
Examples:
|
||||
|
||||
i2c0: i2c@80058000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx28-i2c";
|
||||
reg = <0x80058000 2000>;
|
||||
interrupts = <111 68>;
|
||||
};
|
25
Documentation/devicetree/bindings/mmc/mxs-mmc.txt
Normal file
25
Documentation/devicetree/bindings/mmc/mxs-mmc.txt
Normal file
@ -0,0 +1,25 @@
|
||||
* Freescale MXS MMC controller
|
||||
|
||||
The Freescale MXS Synchronous Serial Ports (SSP) can act as a MMC controller
|
||||
to support MMC, SD, and SDIO types of memory cards.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,<chip>-mmc". The supported chips include
|
||||
imx23 and imx28.
|
||||
- reg: Should contain registers location and length
|
||||
- interrupts: Should contain ERROR and DMA interrupts
|
||||
- fsl,ssp-dma-channel: APBH DMA channel for the SSP
|
||||
- bus-width: Number of data lines, can be <1>, <4>, or <8>
|
||||
|
||||
Optional properties:
|
||||
- wp-gpios: Specify GPIOs for write protection
|
||||
|
||||
Examples:
|
||||
|
||||
ssp0: ssp@80010000 {
|
||||
compatible = "fsl,imx28-mmc";
|
||||
reg = <0x80010000 2000>;
|
||||
interrupts = <96 82>;
|
||||
fsl,ssp-dma-channel = <0>;
|
||||
bus-width = <8>;
|
||||
};
|
@ -468,7 +468,10 @@ config ARCH_MXS
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select CLKDEV_LOOKUP
|
||||
select CLKSRC_MMIO
|
||||
select COMMON_CLK
|
||||
select HAVE_CLK_PREPARE
|
||||
select PINCTRL
|
||||
select USE_OF
|
||||
help
|
||||
Support for Freescale MXS-based family of processors
|
||||
|
||||
|
43
arch/arm/boot/dts/imx23-evk.dts
Normal file
43
arch/arm/boot/dts/imx23-evk.dts
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/ "imx23.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Freescale i.MX23 Evaluation Kit";
|
||||
compatible = "fsl,imx23-evk", "fsl,imx23";
|
||||
|
||||
memory {
|
||||
reg = <0x40000000 0x08000000>;
|
||||
};
|
||||
|
||||
apb@80000000 {
|
||||
apbh@80000000 {
|
||||
ssp0: ssp@80010000 {
|
||||
compatible = "fsl,imx23-mmc";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_8bit_pins_a &mmc0_pins_fixup>;
|
||||
bus-width = <8>;
|
||||
wp-gpios = <&gpio1 30 0>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
apbx@80040000 {
|
||||
duart: serial@80070000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&duart_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
295
arch/arm/boot/dts/imx23.dtsi
Normal file
295
arch/arm/boot/dts/imx23.dtsi
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&icoll>;
|
||||
|
||||
aliases {
|
||||
gpio0 = &gpio0;
|
||||
gpio1 = &gpio1;
|
||||
gpio2 = &gpio2;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
};
|
||||
};
|
||||
|
||||
apb@80000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80000000 0x80000>;
|
||||
ranges;
|
||||
|
||||
apbh@80000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80000000 0x40000>;
|
||||
ranges;
|
||||
|
||||
icoll: interrupt-controller@80000000 {
|
||||
compatible = "fsl,imx23-icoll", "fsl,mxs-icoll";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
reg = <0x80000000 0x2000>;
|
||||
};
|
||||
|
||||
dma-apbh@80004000 {
|
||||
compatible = "fsl,imx23-dma-apbh";
|
||||
reg = <0x80004000 2000>;
|
||||
};
|
||||
|
||||
ecc@80008000 {
|
||||
reg = <0x80008000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
bch@8000a000 {
|
||||
reg = <0x8000a000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpmi@8000c000 {
|
||||
reg = <0x8000c000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssp0: ssp@80010000 {
|
||||
reg = <0x80010000 2000>;
|
||||
interrupts = <15 14>;
|
||||
fsl,ssp-dma-channel = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
etm@80014000 {
|
||||
reg = <0x80014000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pinctrl@80018000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx23-pinctrl", "simple-bus";
|
||||
reg = <0x80018000 2000>;
|
||||
|
||||
gpio0: gpio@0 {
|
||||
compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <16>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio1: gpio@1 {
|
||||
compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <17>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio2: gpio@2 {
|
||||
compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
duart_pins_a: duart@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x11a2 0x11b2>;
|
||||
fsl,drive-strength = <0>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
|
||||
mmc0_8bit_pins_a: mmc0-8bit@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x2020 0x2030 0x2040
|
||||
0x2050 0x0082 0x0092 0x00a2
|
||||
0x00b2 0x2000 0x2010 0x2060>;
|
||||
fsl,drive-strength = <1>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
mmc0_pins_fixup: mmc0-pins-fixup {
|
||||
fsl,pinmux-ids = <0x2010 0x2060>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
digctl@8001c000 {
|
||||
reg = <0x8001c000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
emi@80020000 {
|
||||
reg = <0x80020000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
dma-apbx@80024000 {
|
||||
compatible = "fsl,imx23-dma-apbx";
|
||||
reg = <0x80024000 2000>;
|
||||
};
|
||||
|
||||
dcp@80028000 {
|
||||
reg = <0x80028000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pxp@8002a000 {
|
||||
reg = <0x8002a000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ocotp@8002c000 {
|
||||
reg = <0x8002c000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
axi-ahb@8002e000 {
|
||||
reg = <0x8002e000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
lcdif@80030000 {
|
||||
reg = <0x80030000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssp1: ssp@80034000 {
|
||||
reg = <0x80034000 2000>;
|
||||
interrupts = <2 20>;
|
||||
fsl,ssp-dma-channel = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tvenc@80038000 {
|
||||
reg = <0x80038000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
apbx@80040000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80040000 0x40000>;
|
||||
ranges;
|
||||
|
||||
clkctl@80040000 {
|
||||
reg = <0x80040000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
saif0: saif@80042000 {
|
||||
reg = <0x80042000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
power@80044000 {
|
||||
reg = <0x80044000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
saif1: saif@80046000 {
|
||||
reg = <0x80046000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio-out@80048000 {
|
||||
reg = <0x80048000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio-in@8004c000 {
|
||||
reg = <0x8004c000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
lradc@80050000 {
|
||||
reg = <0x80050000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdif@80054000 {
|
||||
reg = <0x80054000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c@80058000 {
|
||||
reg = <0x80058000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
rtc@8005c000 {
|
||||
reg = <0x8005c000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm@80064000 {
|
||||
reg = <0x80064000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
timrot@80068000 {
|
||||
reg = <0x80068000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart0: serial@8006c000 {
|
||||
reg = <0x8006c000 0x2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart1: serial@8006e000 {
|
||||
reg = <0x8006e000 0x2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
duart: serial@80070000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x80070000 0x2000>;
|
||||
interrupts = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usbphy@8007c000 {
|
||||
reg = <0x8007c000 0x2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ahb@80080000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80080000 0x80000>;
|
||||
ranges;
|
||||
|
||||
usbctrl@80080000 {
|
||||
reg = <0x80080000 0x10000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
114
arch/arm/boot/dts/imx28-evk.dts
Normal file
114
arch/arm/boot/dts/imx28-evk.dts
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/ "imx28.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Freescale i.MX28 Evaluation Kit";
|
||||
compatible = "fsl,imx28-evk", "fsl,imx28";
|
||||
|
||||
memory {
|
||||
reg = <0x40000000 0x08000000>;
|
||||
};
|
||||
|
||||
apb@80000000 {
|
||||
apbh@80000000 {
|
||||
ssp0: ssp@80010000 {
|
||||
compatible = "fsl,imx28-mmc";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_8bit_pins_a
|
||||
&mmc0_cd_cfg &mmc0_sck_cfg>;
|
||||
bus-width = <8>;
|
||||
wp-gpios = <&gpio2 12 0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ssp1: ssp@80012000 {
|
||||
compatible = "fsl,imx28-mmc";
|
||||
bus-width = <8>;
|
||||
wp-gpios = <&gpio0 28 0>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
apbx@80040000 {
|
||||
saif0: saif@80042000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&saif0_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
saif1: saif@80046000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&saif1_pins_a>;
|
||||
fsl,saif-master = <&saif0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
i2c0: i2c@80058000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0_pins_a>;
|
||||
status = "okay";
|
||||
|
||||
sgtl5000: codec@0a {
|
||||
compatible = "fsl,sgtl5000";
|
||||
reg = <0x0a>;
|
||||
VDDA-supply = <®_3p3v>;
|
||||
VDDIO-supply = <®_3p3v>;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
duart: serial@80074000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&duart_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ahb@80080000 {
|
||||
mac0: ethernet@800f0000 {
|
||||
phy-mode = "rmii";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mac0_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
mac1: ethernet@800f4000 {
|
||||
phy-mode = "rmii";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mac1_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
regulators {
|
||||
compatible = "simple-bus";
|
||||
|
||||
reg_3p3v: 3p3v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "3P3V";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "fsl,imx28-evk-sgtl5000",
|
||||
"fsl,mxs-audio-sgtl5000";
|
||||
model = "imx28-evk-sgtl5000";
|
||||
saif-controllers = <&saif0 &saif1>;
|
||||
audio-codec = <&sgtl5000>;
|
||||
};
|
||||
};
|
497
arch/arm/boot/dts/imx28.dtsi
Normal file
497
arch/arm/boot/dts/imx28.dtsi
Normal file
@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&icoll>;
|
||||
|
||||
aliases {
|
||||
gpio0 = &gpio0;
|
||||
gpio1 = &gpio1;
|
||||
gpio2 = &gpio2;
|
||||
gpio3 = &gpio3;
|
||||
gpio4 = &gpio4;
|
||||
saif0 = &saif0;
|
||||
saif1 = &saif1;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
};
|
||||
};
|
||||
|
||||
apb@80000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80000000 0x80000>;
|
||||
ranges;
|
||||
|
||||
apbh@80000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80000000 0x3c900>;
|
||||
ranges;
|
||||
|
||||
icoll: interrupt-controller@80000000 {
|
||||
compatible = "fsl,imx28-icoll", "fsl,mxs-icoll";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
reg = <0x80000000 0x2000>;
|
||||
};
|
||||
|
||||
hsadc@80002000 {
|
||||
reg = <0x80002000 2000>;
|
||||
interrupts = <13 87>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
dma-apbh@80004000 {
|
||||
compatible = "fsl,imx28-dma-apbh";
|
||||
reg = <0x80004000 2000>;
|
||||
};
|
||||
|
||||
perfmon@80006000 {
|
||||
reg = <0x80006000 800>;
|
||||
interrupts = <27>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
bch@8000a000 {
|
||||
reg = <0x8000a000 2000>;
|
||||
interrupts = <41>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpmi@8000c000 {
|
||||
reg = <0x8000c000 2000>;
|
||||
interrupts = <42 88>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssp0: ssp@80010000 {
|
||||
reg = <0x80010000 2000>;
|
||||
interrupts = <96 82>;
|
||||
fsl,ssp-dma-channel = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssp1: ssp@80012000 {
|
||||
reg = <0x80012000 2000>;
|
||||
interrupts = <97 83>;
|
||||
fsl,ssp-dma-channel = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssp2: ssp@80014000 {
|
||||
reg = <0x80014000 2000>;
|
||||
interrupts = <98 84>;
|
||||
fsl,ssp-dma-channel = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssp3: ssp@80016000 {
|
||||
reg = <0x80016000 2000>;
|
||||
interrupts = <99 85>;
|
||||
fsl,ssp-dma-channel = <3>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pinctrl@80018000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx28-pinctrl", "simple-bus";
|
||||
reg = <0x80018000 2000>;
|
||||
|
||||
gpio0: gpio@0 {
|
||||
compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <127>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio1: gpio@1 {
|
||||
compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <126>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio2: gpio@2 {
|
||||
compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <125>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio3: gpio@3 {
|
||||
compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <124>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio4: gpio@4 {
|
||||
compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
|
||||
interrupts = <123>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
duart_pins_a: duart@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x3102 0x3112>;
|
||||
fsl,drive-strength = <0>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
|
||||
mac0_pins_a: mac0@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x4000 0x4010 0x4020
|
||||
0x4030 0x4040 0x4060 0x4070
|
||||
0x4080 0x4100>;
|
||||
fsl,drive-strength = <1>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
mac1_pins_a: mac1@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x40f1 0x4091 0x40a1
|
||||
0x40e1 0x40b1 0x40c1>;
|
||||
fsl,drive-strength = <1>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
mmc0_8bit_pins_a: mmc0-8bit@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x2000 0x2010 0x2020
|
||||
0x2030 0x2040 0x2050 0x2060
|
||||
0x2070 0x2080 0x2090 0x20a0>;
|
||||
fsl,drive-strength = <1>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
mmc0_cd_cfg: mmc0-cd-cfg {
|
||||
fsl,pinmux-ids = <0x2090>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
|
||||
mmc0_sck_cfg: mmc0-sck-cfg {
|
||||
fsl,pinmux-ids = <0x20a0>;
|
||||
fsl,drive-strength = <2>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
|
||||
i2c0_pins_a: i2c0@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x3180 0x3190>;
|
||||
fsl,drive-strength = <1>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
saif0_pins_a: saif0@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids =
|
||||
<0x3140 0x3150 0x3160 0x3170>;
|
||||
fsl,drive-strength = <2>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
saif1_pins_a: saif1@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <0x31a0>;
|
||||
fsl,drive-strength = <2>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
digctl@8001c000 {
|
||||
reg = <0x8001c000 2000>;
|
||||
interrupts = <89>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
etm@80022000 {
|
||||
reg = <0x80022000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
dma-apbx@80024000 {
|
||||
compatible = "fsl,imx28-dma-apbx";
|
||||
reg = <0x80024000 2000>;
|
||||
};
|
||||
|
||||
dcp@80028000 {
|
||||
reg = <0x80028000 2000>;
|
||||
interrupts = <52 53 54>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pxp@8002a000 {
|
||||
reg = <0x8002a000 2000>;
|
||||
interrupts = <39>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ocotp@8002c000 {
|
||||
reg = <0x8002c000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
axi-ahb@8002e000 {
|
||||
reg = <0x8002e000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
lcdif@80030000 {
|
||||
reg = <0x80030000 2000>;
|
||||
interrupts = <38 86>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
can0: can@80032000 {
|
||||
reg = <0x80032000 2000>;
|
||||
interrupts = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
can1: can@80034000 {
|
||||
reg = <0x80034000 2000>;
|
||||
interrupts = <9>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
simdbg@8003c000 {
|
||||
reg = <0x8003c000 200>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
simgpmisel@8003c200 {
|
||||
reg = <0x8003c200 100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
simsspsel@8003c300 {
|
||||
reg = <0x8003c300 100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
simmemsel@8003c400 {
|
||||
reg = <0x8003c400 100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpiomon@8003c500 {
|
||||
reg = <0x8003c500 100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
simenet@8003c700 {
|
||||
reg = <0x8003c700 100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
armjtag@8003c800 {
|
||||
reg = <0x8003c800 100>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
apbx@80040000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80040000 0x40000>;
|
||||
ranges;
|
||||
|
||||
clkctl@80040000 {
|
||||
reg = <0x80040000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
saif0: saif@80042000 {
|
||||
compatible = "fsl,imx28-saif";
|
||||
reg = <0x80042000 2000>;
|
||||
interrupts = <59 80>;
|
||||
fsl,saif-dma-channel = <4>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
power@80044000 {
|
||||
reg = <0x80044000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
saif1: saif@80046000 {
|
||||
compatible = "fsl,imx28-saif";
|
||||
reg = <0x80046000 2000>;
|
||||
interrupts = <58 81>;
|
||||
fsl,saif-dma-channel = <5>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
lradc@80050000 {
|
||||
reg = <0x80050000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdif@80054000 {
|
||||
reg = <0x80054000 2000>;
|
||||
interrupts = <45 66>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
rtc@80056000 {
|
||||
reg = <0x80056000 2000>;
|
||||
interrupts = <28 29>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c0: i2c@80058000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx28-i2c";
|
||||
reg = <0x80058000 2000>;
|
||||
interrupts = <111 68>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c1: i2c@8005a000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx28-i2c";
|
||||
reg = <0x8005a000 2000>;
|
||||
interrupts = <110 69>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm@80064000 {
|
||||
reg = <0x80064000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
timrot@80068000 {
|
||||
reg = <0x80068000 2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart0: serial@8006a000 {
|
||||
reg = <0x8006a000 0x2000>;
|
||||
interrupts = <112 70 71>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart1: serial@8006c000 {
|
||||
reg = <0x8006c000 0x2000>;
|
||||
interrupts = <113 72 73>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart2: serial@8006e000 {
|
||||
reg = <0x8006e000 0x2000>;
|
||||
interrupts = <114 74 75>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart3: serial@80070000 {
|
||||
reg = <0x80070000 0x2000>;
|
||||
interrupts = <115 76 77>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
auart4: serial@80072000 {
|
||||
reg = <0x80072000 0x2000>;
|
||||
interrupts = <116 78 79>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
duart: serial@80074000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x80074000 0x1000>;
|
||||
interrupts = <47>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usbphy0: usbphy@8007c000 {
|
||||
reg = <0x8007c000 0x2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usbphy1: usbphy@8007e000 {
|
||||
reg = <0x8007e000 0x2000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ahb@80080000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x80080000 0x80000>;
|
||||
ranges;
|
||||
|
||||
usbctrl0: usbctrl@80080000 {
|
||||
reg = <0x80080000 0x10000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usbctrl1: usbctrl@80090000 {
|
||||
reg = <0x80090000 0x10000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
dflpt@800c0000 {
|
||||
reg = <0x800c0000 0x10000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mac0: ethernet@800f0000 {
|
||||
compatible = "fsl,imx28-fec";
|
||||
reg = <0x800f0000 0x4000>;
|
||||
interrupts = <101>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mac1: ethernet@800f4000 {
|
||||
compatible = "fsl,imx28-fec";
|
||||
reg = <0x800f4000 0x4000>;
|
||||
interrupts = <102>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
switch@800f8000 {
|
||||
reg = <0x800f8000 0x8000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
@ -22,6 +22,7 @@ CONFIG_BLK_DEV_INTEGRITY=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARCH_MXS=y
|
||||
CONFIG_MACH_MXS_DT=y
|
||||
CONFIG_MACH_MX23EVK=y
|
||||
CONFIG_MACH_MX28EVK=y
|
||||
CONFIG_MACH_STMP378X_DEVB=y
|
||||
|
@ -842,6 +842,8 @@ config SOC_IMX6Q
|
||||
select HAVE_IMX_MMDC
|
||||
select HAVE_IMX_SRC
|
||||
select HAVE_SMP
|
||||
select PINCTRL
|
||||
select PINCTRL_IMX6Q
|
||||
select USE_OF
|
||||
|
||||
help
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/common.h>
|
||||
@ -81,6 +82,8 @@ static void __init imx51_dt_init(void)
|
||||
|
||||
of_irq_init(imx51_irq_match);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
|
||||
node = of_find_matching_node(NULL, imx51_iomuxc_of_match);
|
||||
if (node) {
|
||||
of_id = of_match_node(imx51_iomuxc_of_match, node);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/common.h>
|
||||
@ -88,6 +89,8 @@ static void __init imx53_dt_init(void)
|
||||
|
||||
of_irq_init(imx53_irq_match);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
|
||||
node = of_find_matching_node(NULL, imx53_iomuxc_of_match);
|
||||
if (node) {
|
||||
of_id = of_match_node(imx53_iomuxc_of_match, node);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/micrel_phy.h>
|
||||
#include <asm/smp_twd.h>
|
||||
@ -77,6 +78,12 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
|
||||
|
||||
static void __init imx6q_init_machine(void)
|
||||
{
|
||||
/*
|
||||
* This should be removed when all imx6q boards have pinctrl
|
||||
* states for devices defined in device tree.
|
||||
*/
|
||||
pinctrl_provide_dummies();
|
||||
|
||||
if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
|
||||
phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
|
||||
ksz9021rn_phy_fixup);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
@ -58,4 +59,5 @@ void __init imx1_soc_init(void)
|
||||
MX1_GPIO_INT_PORTC, 0);
|
||||
mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
|
||||
MX1_GPIO_INT_PORTD, 0);
|
||||
pinctrl_provide_dummies();
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/devices-common.h>
|
||||
@ -88,6 +89,7 @@ void __init imx21_soc_init(void)
|
||||
mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
imx_add_imx_dma();
|
||||
platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
|
||||
ARRAY_SIZE(imx21_audmux_res));
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mach/map.h>
|
||||
@ -95,6 +96,7 @@ void __init imx25_soc_init(void)
|
||||
mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
|
||||
mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
/* i.mx25 has the i.mx35 type sdma */
|
||||
imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
|
||||
/* i.mx25 has the i.mx31 type audmux */
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/devices-common.h>
|
||||
@ -89,6 +90,7 @@ void __init imx27_soc_init(void)
|
||||
mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
imx_add_imx_dma();
|
||||
/* imx27 has the imx21 type audmux */
|
||||
platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system_misc.h>
|
||||
@ -267,6 +268,7 @@ void __init imx35_soc_init(void)
|
||||
mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
if (to_version == 1) {
|
||||
strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin",
|
||||
strlen(imx35_sdma_pdata.fw_name));
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/mach/map.h>
|
||||
@ -223,6 +224,7 @@ void __init imx53_soc_init(void)
|
||||
mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
/* i.mx53 has the i.mx35 type sdma */
|
||||
imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
|
||||
|
||||
|
@ -7,16 +7,28 @@ config MXS_OCOTP
|
||||
|
||||
config SOC_IMX23
|
||||
bool
|
||||
select ARM_AMBA
|
||||
select CPU_ARM926T
|
||||
select HAVE_PWM
|
||||
select PINCTRL_IMX23
|
||||
|
||||
config SOC_IMX28
|
||||
bool
|
||||
select ARM_AMBA
|
||||
select CPU_ARM926T
|
||||
select HAVE_PWM
|
||||
select PINCTRL_IMX28
|
||||
|
||||
comment "MXS platforms:"
|
||||
|
||||
config MACH_MXS_DT
|
||||
bool "Support MXS platforms from device tree"
|
||||
select SOC_IMX23
|
||||
select SOC_IMX28
|
||||
help
|
||||
Include support for Freescale MXS platforms(i.MX23 and i.MX28)
|
||||
using the device tree for discovery
|
||||
|
||||
config MACH_STMP378X_DEVB
|
||||
bool "Support STMP378x_devb Platform"
|
||||
select SOC_IMX23
|
||||
|
@ -1,12 +1,10 @@
|
||||
# Common support
|
||||
obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o mm.o
|
||||
obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o
|
||||
|
||||
obj-$(CONFIG_MXS_OCOTP) += ocotp.o
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
|
||||
obj-$(CONFIG_SOC_IMX23) += clock-mx23.o
|
||||
obj-$(CONFIG_SOC_IMX28) += clock-mx28.o
|
||||
|
||||
obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
|
||||
obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
|
||||
obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
|
||||
obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
|
||||
|
@ -1,536 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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/mm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/clkdev.h>
|
||||
|
||||
#include <asm/clkdev.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <mach/mx23.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/clock.h>
|
||||
|
||||
#include "regs-clkctrl-mx23.h"
|
||||
|
||||
#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
|
||||
#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
|
||||
|
||||
#define PARENT_RATE_SHIFT 8
|
||||
|
||||
static int _raw_clk_enable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (clk->enable_reg) {
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg &= ~(1 << clk->enable_shift);
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _raw_clk_disable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (clk->enable_reg) {
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg |= 1 << clk->enable_shift;
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ref_xtal_clk
|
||||
*/
|
||||
static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return 24000000;
|
||||
}
|
||||
|
||||
static struct clk ref_xtal_clk = {
|
||||
.get_rate = ref_xtal_clk_get_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* pll_clk
|
||||
*/
|
||||
static unsigned long pll_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return 480000000;
|
||||
}
|
||||
|
||||
static int pll_clk_enable(struct clk *clk)
|
||||
{
|
||||
__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
|
||||
BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
|
||||
|
||||
/* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
|
||||
* and is incorrect (excessive). Per definition of the PLLCTRL0
|
||||
* POWER field, waiting at least 10us.
|
||||
*/
|
||||
udelay(10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pll_clk_disable(struct clk *clk)
|
||||
{
|
||||
__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
|
||||
BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
|
||||
}
|
||||
|
||||
static struct clk pll_clk = {
|
||||
.get_rate = pll_clk_get_rate,
|
||||
.enable = pll_clk_enable,
|
||||
.disable = pll_clk_disable,
|
||||
.parent = &ref_xtal_clk,
|
||||
};
|
||||
|
||||
/*
|
||||
* ref_clk
|
||||
*/
|
||||
#define _CLK_GET_RATE_REF(name, sr, ss) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
unsigned long parent_rate; \
|
||||
u32 reg, div; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
|
||||
div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
\
|
||||
return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
|
||||
div, PARENT_RATE_SHIFT); \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
|
||||
_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
|
||||
_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
|
||||
_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
|
||||
|
||||
#define _DEFINE_CLOCK_REF(name, er, es) \
|
||||
static struct clk name = { \
|
||||
.enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
|
||||
.enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
|
||||
.get_rate = name##_get_rate, \
|
||||
.enable = _raw_clk_enable, \
|
||||
.disable = _raw_clk_disable, \
|
||||
.parent = &pll_clk, \
|
||||
}
|
||||
|
||||
_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
|
||||
_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
|
||||
_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
|
||||
_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
|
||||
|
||||
/*
|
||||
* General clocks
|
||||
*
|
||||
* clk_get_rate
|
||||
*/
|
||||
static unsigned long rtc_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
/* ref_xtal_clk is implemented as the only parent */
|
||||
return clk_get_rate(clk->parent) / 768;
|
||||
}
|
||||
|
||||
static unsigned long clk32k_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk->parent->get_rate(clk->parent) / 750;
|
||||
}
|
||||
|
||||
#define _CLK_GET_RATE(name, rs) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
u32 reg, div; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
|
||||
\
|
||||
if (clk->parent == &ref_xtal_clk) \
|
||||
div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
|
||||
BP_CLKCTRL_##rs##_DIV_XTAL; \
|
||||
else \
|
||||
div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
|
||||
BP_CLKCTRL_##rs##_DIV_##rs; \
|
||||
\
|
||||
if (!div) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
return clk_get_rate(clk->parent) / div; \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE(cpu_clk, CPU)
|
||||
_CLK_GET_RATE(emi_clk, EMI)
|
||||
|
||||
#define _CLK_GET_RATE1(name, rs) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
u32 reg, div; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
|
||||
div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
|
||||
\
|
||||
if (!div) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
return clk_get_rate(clk->parent) / div; \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE1(hbus_clk, HBUS)
|
||||
_CLK_GET_RATE1(xbus_clk, XBUS)
|
||||
_CLK_GET_RATE1(ssp_clk, SSP)
|
||||
_CLK_GET_RATE1(gpmi_clk, GPMI)
|
||||
_CLK_GET_RATE1(lcdif_clk, PIX)
|
||||
|
||||
#define _CLK_GET_RATE_STUB(name) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
return clk_get_rate(clk->parent); \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE_STUB(uart_clk)
|
||||
_CLK_GET_RATE_STUB(audio_clk)
|
||||
_CLK_GET_RATE_STUB(pwm_clk)
|
||||
|
||||
/*
|
||||
* clk_set_rate
|
||||
*/
|
||||
static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 reg, bm_busy, div_max, d, f, div, frac;
|
||||
unsigned long diff, parent_rate, calc_rate;
|
||||
|
||||
parent_rate = clk_get_rate(clk->parent);
|
||||
|
||||
if (clk->parent == &ref_xtal_clk) {
|
||||
div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
|
||||
bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
|
||||
div = DIV_ROUND_UP(parent_rate, rate);
|
||||
if (div == 0 || div > div_max)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
|
||||
bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
|
||||
rate >>= PARENT_RATE_SHIFT;
|
||||
parent_rate >>= PARENT_RATE_SHIFT;
|
||||
diff = parent_rate;
|
||||
div = frac = 1;
|
||||
for (d = 1; d <= div_max; d++) {
|
||||
f = parent_rate * 18 / d / rate;
|
||||
if ((parent_rate * 18 / d) % rate)
|
||||
f++;
|
||||
if (f < 18 || f > 35)
|
||||
continue;
|
||||
|
||||
calc_rate = parent_rate * 18 / f / d;
|
||||
if (calc_rate > rate)
|
||||
continue;
|
||||
|
||||
if (rate - calc_rate < diff) {
|
||||
frac = f;
|
||||
div = d;
|
||||
diff = rate - calc_rate;
|
||||
}
|
||||
|
||||
if (diff == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (diff == parent_rate)
|
||||
return -EINVAL;
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
|
||||
reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
|
||||
reg |= frac;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
|
||||
}
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
|
||||
reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
|
||||
reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
|
||||
|
||||
mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define _CLK_SET_RATE(name, dr) \
|
||||
static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
||||
{ \
|
||||
u32 reg, div_max, div; \
|
||||
unsigned long parent_rate; \
|
||||
\
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
|
||||
\
|
||||
div = DIV_ROUND_UP(parent_rate, rate); \
|
||||
if (div == 0 || div > div_max) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
|
||||
reg &= ~BM_CLKCTRL_##dr##_DIV; \
|
||||
reg |= div << BP_CLKCTRL_##dr##_DIV; \
|
||||
if (reg & (1 << clk->enable_shift)) { \
|
||||
pr_err("%s: clock is gated\n", __func__); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
|
||||
\
|
||||
mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
_CLK_SET_RATE(xbus_clk, XBUS)
|
||||
_CLK_SET_RATE(ssp_clk, SSP)
|
||||
_CLK_SET_RATE(gpmi_clk, GPMI)
|
||||
_CLK_SET_RATE(lcdif_clk, PIX)
|
||||
|
||||
#define _CLK_SET_RATE_STUB(name) \
|
||||
static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
||||
{ \
|
||||
return -EINVAL; \
|
||||
}
|
||||
|
||||
_CLK_SET_RATE_STUB(emi_clk)
|
||||
_CLK_SET_RATE_STUB(uart_clk)
|
||||
_CLK_SET_RATE_STUB(audio_clk)
|
||||
_CLK_SET_RATE_STUB(pwm_clk)
|
||||
_CLK_SET_RATE_STUB(clk32k_clk)
|
||||
|
||||
/*
|
||||
* clk_set_parent
|
||||
*/
|
||||
#define _CLK_SET_PARENT(name, bit) \
|
||||
static int name##_set_parent(struct clk *clk, struct clk *parent) \
|
||||
{ \
|
||||
if (parent != clk->parent) { \
|
||||
__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
|
||||
clk->parent = parent; \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
_CLK_SET_PARENT(cpu_clk, CPU)
|
||||
_CLK_SET_PARENT(emi_clk, EMI)
|
||||
_CLK_SET_PARENT(ssp_clk, SSP)
|
||||
_CLK_SET_PARENT(gpmi_clk, GPMI)
|
||||
_CLK_SET_PARENT(lcdif_clk, PIX)
|
||||
|
||||
#define _CLK_SET_PARENT_STUB(name) \
|
||||
static int name##_set_parent(struct clk *clk, struct clk *parent) \
|
||||
{ \
|
||||
if (parent != clk->parent) \
|
||||
return -EINVAL; \
|
||||
else \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
_CLK_SET_PARENT_STUB(uart_clk)
|
||||
_CLK_SET_PARENT_STUB(audio_clk)
|
||||
_CLK_SET_PARENT_STUB(pwm_clk)
|
||||
_CLK_SET_PARENT_STUB(clk32k_clk)
|
||||
|
||||
/*
|
||||
* clk definition
|
||||
*/
|
||||
static struct clk cpu_clk = {
|
||||
.get_rate = cpu_clk_get_rate,
|
||||
.set_rate = cpu_clk_set_rate,
|
||||
.set_parent = cpu_clk_set_parent,
|
||||
.parent = &ref_cpu_clk,
|
||||
};
|
||||
|
||||
static struct clk hbus_clk = {
|
||||
.get_rate = hbus_clk_get_rate,
|
||||
.parent = &cpu_clk,
|
||||
};
|
||||
|
||||
static struct clk xbus_clk = {
|
||||
.get_rate = xbus_clk_get_rate,
|
||||
.set_rate = xbus_clk_set_rate,
|
||||
.parent = &ref_xtal_clk,
|
||||
};
|
||||
|
||||
static struct clk rtc_clk = {
|
||||
.get_rate = rtc_clk_get_rate,
|
||||
.parent = &ref_xtal_clk,
|
||||
};
|
||||
|
||||
/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
|
||||
static struct clk usb_clk = {
|
||||
.enable_reg = DIGCTRL_BASE_ADDR,
|
||||
.enable_shift = 2,
|
||||
.enable = _raw_clk_enable,
|
||||
.disable = _raw_clk_disable,
|
||||
.parent = &pll_clk,
|
||||
};
|
||||
|
||||
#define _DEFINE_CLOCK(name, er, es, p) \
|
||||
static struct clk name = { \
|
||||
.enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
|
||||
.enable_shift = BP_CLKCTRL_##er##_##es, \
|
||||
.get_rate = name##_get_rate, \
|
||||
.set_rate = name##_set_rate, \
|
||||
.set_parent = name##_set_parent, \
|
||||
.enable = _raw_clk_enable, \
|
||||
.disable = _raw_clk_disable, \
|
||||
.parent = p, \
|
||||
}
|
||||
|
||||
_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
|
||||
|
||||
#define _REGISTER_CLOCK(d, n, c) \
|
||||
{ \
|
||||
.dev_id = d, \
|
||||
.con_id = n, \
|
||||
.clk = &c, \
|
||||
},
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* for amba bus driver */
|
||||
_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
|
||||
/* for amba-pl011 driver */
|
||||
_REGISTER_CLOCK("duart", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("rtc", NULL, rtc_clk)
|
||||
_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
|
||||
_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
|
||||
_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
|
||||
_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp_clk)
|
||||
_REGISTER_CLOCK(NULL, "usb", usb_clk)
|
||||
_REGISTER_CLOCK(NULL, "audio", audio_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
|
||||
_REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk)
|
||||
};
|
||||
|
||||
static int clk_misc_init(void)
|
||||
{
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
/* Fix up parent per register setting */
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
|
||||
cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
|
||||
&ref_xtal_clk : &ref_cpu_clk;
|
||||
emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
|
||||
&ref_xtal_clk : &ref_emi_clk;
|
||||
ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
|
||||
&ref_xtal_clk : &ref_io_clk;
|
||||
gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
|
||||
&ref_xtal_clk : &ref_io_clk;
|
||||
lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
|
||||
&ref_xtal_clk : &ref_pix_clk;
|
||||
|
||||
/* Use int div over frac when both are available */
|
||||
__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
|
||||
__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
|
||||
__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
|
||||
reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
|
||||
reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
|
||||
reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
|
||||
reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
|
||||
|
||||
/*
|
||||
* Set safe hbus clock divider. A divider of 3 ensure that
|
||||
* the Vddd voltage required for the cpu clock is sufficiently
|
||||
* high for the hbus clock.
|
||||
*/
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
|
||||
reg &= BM_CLKCTRL_HBUS_DIV;
|
||||
reg |= 3 << BP_CLKCTRL_HBUS_DIV;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
|
||||
|
||||
ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
|
||||
|
||||
/* Gate off cpu clock in WFI for power saving */
|
||||
__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
|
||||
|
||||
/*
|
||||
* 480 MHz seems too high to be ssp clock source directly,
|
||||
* so set frac to get a 288 MHz ref_io.
|
||||
*/
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
|
||||
reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
|
||||
reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __init mx23_clocks_init(void)
|
||||
{
|
||||
clk_misc_init();
|
||||
|
||||
/*
|
||||
* source ssp clock from ref_io than ref_xtal,
|
||||
* as ref_xtal only provides 24 MHz as maximum.
|
||||
*/
|
||||
clk_set_parent(&ssp_clk, &ref_io_clk);
|
||||
|
||||
clk_prepare_enable(&cpu_clk);
|
||||
clk_prepare_enable(&hbus_clk);
|
||||
clk_prepare_enable(&xbus_clk);
|
||||
clk_prepare_enable(&emi_clk);
|
||||
clk_prepare_enable(&uart_clk);
|
||||
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,803 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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/mm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/clkdev.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <mach/mx28.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/digctl.h>
|
||||
|
||||
#include "regs-clkctrl-mx28.h"
|
||||
|
||||
#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
|
||||
#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
|
||||
|
||||
#define PARENT_RATE_SHIFT 8
|
||||
|
||||
static struct clk pll2_clk;
|
||||
static struct clk cpu_clk;
|
||||
static struct clk emi_clk;
|
||||
static struct clk saif0_clk;
|
||||
static struct clk saif1_clk;
|
||||
static struct clk clk32k_clk;
|
||||
static DEFINE_SPINLOCK(clkmux_lock);
|
||||
|
||||
/*
|
||||
* HW_SAIF_CLKMUX_SEL:
|
||||
* DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
|
||||
* clock pins selected for SAIF1 input clocks.
|
||||
* CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
|
||||
* SAIF0 clock inputs selected for SAIF1 input clocks.
|
||||
* EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
|
||||
* clocks.
|
||||
* EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
|
||||
* clocks.
|
||||
*/
|
||||
int mxs_saif_clkmux_select(unsigned int clkmux)
|
||||
{
|
||||
if (clkmux > 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&clkmux_lock);
|
||||
__raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
|
||||
DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
|
||||
__raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
|
||||
DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
|
||||
spin_unlock(&clkmux_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _raw_clk_enable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (clk->enable_reg) {
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg &= ~(1 << clk->enable_shift);
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _raw_clk_disable(struct clk *clk)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (clk->enable_reg) {
|
||||
reg = __raw_readl(clk->enable_reg);
|
||||
reg |= 1 << clk->enable_shift;
|
||||
__raw_writel(reg, clk->enable_reg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ref_xtal_clk
|
||||
*/
|
||||
static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return 24000000;
|
||||
}
|
||||
|
||||
static struct clk ref_xtal_clk = {
|
||||
.get_rate = ref_xtal_clk_get_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* pll_clk
|
||||
*/
|
||||
static unsigned long pll0_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return 480000000;
|
||||
}
|
||||
|
||||
static unsigned long pll1_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return 480000000;
|
||||
}
|
||||
|
||||
static unsigned long pll2_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return 50000000;
|
||||
}
|
||||
|
||||
#define _CLK_ENABLE_PLL(name, r, g) \
|
||||
static int name##_enable(struct clk *clk) \
|
||||
{ \
|
||||
__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
|
||||
udelay(10); \
|
||||
\
|
||||
if (clk == &pll2_clk) \
|
||||
__raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
|
||||
else \
|
||||
__raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
|
||||
_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
|
||||
_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
|
||||
|
||||
#define _CLK_DISABLE_PLL(name, r, g) \
|
||||
static void name##_disable(struct clk *clk) \
|
||||
{ \
|
||||
__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
|
||||
\
|
||||
if (clk == &pll2_clk) \
|
||||
__raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
|
||||
else \
|
||||
__raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
|
||||
\
|
||||
}
|
||||
|
||||
_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
|
||||
_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
|
||||
_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
|
||||
|
||||
#define _DEFINE_CLOCK_PLL(name) \
|
||||
static struct clk name = { \
|
||||
.get_rate = name##_get_rate, \
|
||||
.enable = name##_enable, \
|
||||
.disable = name##_disable, \
|
||||
.parent = &ref_xtal_clk, \
|
||||
}
|
||||
|
||||
_DEFINE_CLOCK_PLL(pll0_clk);
|
||||
_DEFINE_CLOCK_PLL(pll1_clk);
|
||||
_DEFINE_CLOCK_PLL(pll2_clk);
|
||||
|
||||
/*
|
||||
* ref_clk
|
||||
*/
|
||||
#define _CLK_GET_RATE_REF(name, sr, ss) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
unsigned long parent_rate; \
|
||||
u32 reg, div; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
|
||||
div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
\
|
||||
return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
|
||||
div, PARENT_RATE_SHIFT); \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
|
||||
_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
|
||||
_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
|
||||
_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
|
||||
_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
|
||||
_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
|
||||
|
||||
#define _DEFINE_CLOCK_REF(name, er, es) \
|
||||
static struct clk name = { \
|
||||
.enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
|
||||
.enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
|
||||
.get_rate = name##_get_rate, \
|
||||
.enable = _raw_clk_enable, \
|
||||
.disable = _raw_clk_disable, \
|
||||
.parent = &pll0_clk, \
|
||||
}
|
||||
|
||||
_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
|
||||
_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
|
||||
_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
|
||||
_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
|
||||
_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
|
||||
_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
|
||||
|
||||
/*
|
||||
* General clocks
|
||||
*
|
||||
* clk_get_rate
|
||||
*/
|
||||
static unsigned long lradc_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk_get_rate(clk->parent) / 16;
|
||||
}
|
||||
|
||||
static unsigned long rtc_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
/* ref_xtal_clk is implemented as the only parent */
|
||||
return clk_get_rate(clk->parent) / 768;
|
||||
}
|
||||
|
||||
static unsigned long clk32k_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk->parent->get_rate(clk->parent) / 750;
|
||||
}
|
||||
|
||||
static unsigned long spdif_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk_get_rate(clk->parent) / 4;
|
||||
}
|
||||
|
||||
#define _CLK_GET_RATE(name, rs) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
u32 reg, div; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
|
||||
\
|
||||
if (clk->parent == &ref_xtal_clk) \
|
||||
div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
|
||||
BP_CLKCTRL_##rs##_DIV_XTAL; \
|
||||
else \
|
||||
div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
|
||||
BP_CLKCTRL_##rs##_DIV_##rs; \
|
||||
\
|
||||
if (!div) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
return clk_get_rate(clk->parent) / div; \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE(cpu_clk, CPU)
|
||||
_CLK_GET_RATE(emi_clk, EMI)
|
||||
|
||||
#define _CLK_GET_RATE1(name, rs) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
u32 reg, div; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
|
||||
div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
|
||||
\
|
||||
if (!div) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
if (clk == &saif0_clk || clk == &saif1_clk) \
|
||||
return clk_get_rate(clk->parent) >> 16 * div; \
|
||||
else \
|
||||
return clk_get_rate(clk->parent) / div; \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE1(hbus_clk, HBUS)
|
||||
_CLK_GET_RATE1(xbus_clk, XBUS)
|
||||
_CLK_GET_RATE1(ssp0_clk, SSP0)
|
||||
_CLK_GET_RATE1(ssp1_clk, SSP1)
|
||||
_CLK_GET_RATE1(ssp2_clk, SSP2)
|
||||
_CLK_GET_RATE1(ssp3_clk, SSP3)
|
||||
_CLK_GET_RATE1(gpmi_clk, GPMI)
|
||||
_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
|
||||
_CLK_GET_RATE1(saif0_clk, SAIF0)
|
||||
_CLK_GET_RATE1(saif1_clk, SAIF1)
|
||||
|
||||
#define _CLK_GET_RATE_STUB(name) \
|
||||
static unsigned long name##_get_rate(struct clk *clk) \
|
||||
{ \
|
||||
return clk_get_rate(clk->parent); \
|
||||
}
|
||||
|
||||
_CLK_GET_RATE_STUB(uart_clk)
|
||||
_CLK_GET_RATE_STUB(pwm_clk)
|
||||
_CLK_GET_RATE_STUB(can0_clk)
|
||||
_CLK_GET_RATE_STUB(can1_clk)
|
||||
_CLK_GET_RATE_STUB(fec_clk)
|
||||
|
||||
/*
|
||||
* clk_set_rate
|
||||
*/
|
||||
/* fool compiler */
|
||||
#define BM_CLKCTRL_CPU_DIV 0
|
||||
#define BP_CLKCTRL_CPU_DIV 0
|
||||
#define BM_CLKCTRL_CPU_BUSY 0
|
||||
|
||||
#define _CLK_SET_RATE(name, dr, fr, fs) \
|
||||
static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
||||
{ \
|
||||
u32 reg, bm_busy, div_max, d, f, div, frac; \
|
||||
unsigned long diff, parent_rate, calc_rate; \
|
||||
\
|
||||
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
|
||||
bm_busy = BM_CLKCTRL_##dr##_BUSY; \
|
||||
\
|
||||
if (clk->parent == &ref_xtal_clk) { \
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
div = DIV_ROUND_UP(parent_rate, rate); \
|
||||
if (clk == &cpu_clk) { \
|
||||
div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
|
||||
BP_CLKCTRL_CPU_DIV_XTAL; \
|
||||
bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
|
||||
} \
|
||||
if (div == 0 || div > div_max) \
|
||||
return -EINVAL; \
|
||||
} else { \
|
||||
/* \
|
||||
* hack alert: this block modifies clk->parent, too, \
|
||||
* so the base to use it the grand parent. \
|
||||
*/ \
|
||||
parent_rate = clk_get_rate(clk->parent->parent); \
|
||||
rate >>= PARENT_RATE_SHIFT; \
|
||||
parent_rate >>= PARENT_RATE_SHIFT; \
|
||||
diff = parent_rate; \
|
||||
div = frac = 1; \
|
||||
if (clk == &cpu_clk) { \
|
||||
div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
|
||||
BP_CLKCTRL_CPU_DIV_CPU; \
|
||||
bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
|
||||
} \
|
||||
for (d = 1; d <= div_max; d++) { \
|
||||
f = parent_rate * 18 / d / rate; \
|
||||
if ((parent_rate * 18 / d) % rate) \
|
||||
f++; \
|
||||
if (f < 18 || f > 35) \
|
||||
continue; \
|
||||
\
|
||||
calc_rate = parent_rate * 18 / f / d; \
|
||||
if (calc_rate > rate) \
|
||||
continue; \
|
||||
\
|
||||
if (rate - calc_rate < diff) { \
|
||||
frac = f; \
|
||||
div = d; \
|
||||
diff = rate - calc_rate; \
|
||||
} \
|
||||
\
|
||||
if (diff == 0) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
if (diff == parent_rate) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
|
||||
reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
|
||||
reg |= frac << BP_CLKCTRL_##fr##_##fs##FRAC; \
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
|
||||
} \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
|
||||
if (clk == &cpu_clk) { \
|
||||
reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
|
||||
reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
|
||||
} else { \
|
||||
reg &= ~BM_CLKCTRL_##dr##_DIV; \
|
||||
reg |= div << BP_CLKCTRL_##dr##_DIV; \
|
||||
if (reg & (1 << clk->enable_shift)) { \
|
||||
pr_err("%s: clock is gated\n", __func__); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
} \
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
|
||||
\
|
||||
return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \
|
||||
}
|
||||
|
||||
_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
|
||||
_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
|
||||
_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
|
||||
_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
|
||||
_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
|
||||
_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
|
||||
_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
|
||||
|
||||
#define _CLK_SET_RATE1(name, dr) \
|
||||
static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
||||
{ \
|
||||
u32 reg, div_max, div; \
|
||||
unsigned long parent_rate; \
|
||||
\
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
|
||||
\
|
||||
div = DIV_ROUND_UP(parent_rate, rate); \
|
||||
if (div == 0 || div > div_max) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
|
||||
reg &= ~BM_CLKCTRL_##dr##_DIV; \
|
||||
reg |= div << BP_CLKCTRL_##dr##_DIV; \
|
||||
if (reg & (1 << clk->enable_shift)) { \
|
||||
pr_err("%s: clock is gated\n", __func__); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
|
||||
\
|
||||
return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
|
||||
}
|
||||
|
||||
_CLK_SET_RATE1(xbus_clk, XBUS)
|
||||
|
||||
/* saif clock uses 16 bits frac div */
|
||||
#define _CLK_SET_RATE_SAIF(name, rs) \
|
||||
static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
||||
{ \
|
||||
u16 div; \
|
||||
u32 reg; \
|
||||
u64 lrate; \
|
||||
unsigned long parent_rate; \
|
||||
\
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
if (rate > parent_rate) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
lrate = (u64)rate << 16; \
|
||||
do_div(lrate, parent_rate); \
|
||||
div = (u16)lrate; \
|
||||
\
|
||||
if (!div) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
|
||||
reg &= ~BM_CLKCTRL_##rs##_DIV; \
|
||||
reg |= div << BP_CLKCTRL_##rs##_DIV; \
|
||||
if (reg & (1 << clk->enable_shift)) { \
|
||||
pr_err("%s: clock is gated\n", __func__); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
|
||||
\
|
||||
return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
|
||||
}
|
||||
|
||||
_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
|
||||
_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
|
||||
|
||||
#define _CLK_SET_RATE_STUB(name) \
|
||||
static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
||||
{ \
|
||||
return -EINVAL; \
|
||||
}
|
||||
|
||||
_CLK_SET_RATE_STUB(emi_clk)
|
||||
_CLK_SET_RATE_STUB(uart_clk)
|
||||
_CLK_SET_RATE_STUB(pwm_clk)
|
||||
_CLK_SET_RATE_STUB(spdif_clk)
|
||||
_CLK_SET_RATE_STUB(clk32k_clk)
|
||||
_CLK_SET_RATE_STUB(can0_clk)
|
||||
_CLK_SET_RATE_STUB(can1_clk)
|
||||
_CLK_SET_RATE_STUB(fec_clk)
|
||||
|
||||
/*
|
||||
* clk_set_parent
|
||||
*/
|
||||
#define _CLK_SET_PARENT(name, bit) \
|
||||
static int name##_set_parent(struct clk *clk, struct clk *parent) \
|
||||
{ \
|
||||
if (parent != clk->parent) { \
|
||||
__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
|
||||
clk->parent = parent; \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
_CLK_SET_PARENT(cpu_clk, CPU)
|
||||
_CLK_SET_PARENT(emi_clk, EMI)
|
||||
_CLK_SET_PARENT(ssp0_clk, SSP0)
|
||||
_CLK_SET_PARENT(ssp1_clk, SSP1)
|
||||
_CLK_SET_PARENT(ssp2_clk, SSP2)
|
||||
_CLK_SET_PARENT(ssp3_clk, SSP3)
|
||||
_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
|
||||
_CLK_SET_PARENT(gpmi_clk, GPMI)
|
||||
_CLK_SET_PARENT(saif0_clk, SAIF0)
|
||||
_CLK_SET_PARENT(saif1_clk, SAIF1)
|
||||
|
||||
#define _CLK_SET_PARENT_STUB(name) \
|
||||
static int name##_set_parent(struct clk *clk, struct clk *parent) \
|
||||
{ \
|
||||
if (parent != clk->parent) \
|
||||
return -EINVAL; \
|
||||
else \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
_CLK_SET_PARENT_STUB(pwm_clk)
|
||||
_CLK_SET_PARENT_STUB(uart_clk)
|
||||
_CLK_SET_PARENT_STUB(clk32k_clk)
|
||||
_CLK_SET_PARENT_STUB(spdif_clk)
|
||||
_CLK_SET_PARENT_STUB(fec_clk)
|
||||
_CLK_SET_PARENT_STUB(can0_clk)
|
||||
_CLK_SET_PARENT_STUB(can1_clk)
|
||||
|
||||
/*
|
||||
* clk definition
|
||||
*/
|
||||
static struct clk cpu_clk = {
|
||||
.get_rate = cpu_clk_get_rate,
|
||||
.set_rate = cpu_clk_set_rate,
|
||||
.set_parent = cpu_clk_set_parent,
|
||||
.parent = &ref_cpu_clk,
|
||||
};
|
||||
|
||||
static struct clk hbus_clk = {
|
||||
.get_rate = hbus_clk_get_rate,
|
||||
.parent = &cpu_clk,
|
||||
};
|
||||
|
||||
static struct clk xbus_clk = {
|
||||
.get_rate = xbus_clk_get_rate,
|
||||
.set_rate = xbus_clk_set_rate,
|
||||
.parent = &ref_xtal_clk,
|
||||
};
|
||||
|
||||
static struct clk lradc_clk = {
|
||||
.get_rate = lradc_clk_get_rate,
|
||||
.parent = &clk32k_clk,
|
||||
};
|
||||
|
||||
static struct clk rtc_clk = {
|
||||
.get_rate = rtc_clk_get_rate,
|
||||
.parent = &ref_xtal_clk,
|
||||
};
|
||||
|
||||
/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
|
||||
static struct clk usb0_clk = {
|
||||
.enable_reg = DIGCTRL_BASE_ADDR,
|
||||
.enable_shift = 2,
|
||||
.enable = _raw_clk_enable,
|
||||
.disable = _raw_clk_disable,
|
||||
.parent = &pll0_clk,
|
||||
};
|
||||
|
||||
static struct clk usb1_clk = {
|
||||
.enable_reg = DIGCTRL_BASE_ADDR,
|
||||
.enable_shift = 16,
|
||||
.enable = _raw_clk_enable,
|
||||
.disable = _raw_clk_disable,
|
||||
.parent = &pll1_clk,
|
||||
};
|
||||
|
||||
#define _DEFINE_CLOCK(name, er, es, p) \
|
||||
static struct clk name = { \
|
||||
.enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
|
||||
.enable_shift = BP_CLKCTRL_##er##_##es, \
|
||||
.get_rate = name##_get_rate, \
|
||||
.set_rate = name##_set_rate, \
|
||||
.set_parent = name##_set_parent, \
|
||||
.enable = _raw_clk_enable, \
|
||||
.disable = _raw_clk_disable, \
|
||||
.parent = p, \
|
||||
}
|
||||
|
||||
_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
|
||||
_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
|
||||
_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
|
||||
|
||||
#define _REGISTER_CLOCK(d, n, c) \
|
||||
{ \
|
||||
.dev_id = d, \
|
||||
.con_id = n, \
|
||||
.clk = &c, \
|
||||
},
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* for amba bus driver */
|
||||
_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
|
||||
/* for amba-pl011 driver */
|
||||
_REGISTER_CLOCK("duart", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
|
||||
_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
|
||||
_REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk)
|
||||
_REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
|
||||
_REGISTER_CLOCK("rtc", NULL, rtc_clk)
|
||||
_REGISTER_CLOCK("pll2", NULL, pll2_clk)
|
||||
_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
|
||||
_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
|
||||
_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
|
||||
_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
|
||||
_REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
|
||||
_REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
|
||||
_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
|
||||
_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
|
||||
_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
|
||||
_REGISTER_CLOCK(NULL, "usb1", usb1_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.5", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.6", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK("mxs-pwm.7", NULL, pwm_clk)
|
||||
_REGISTER_CLOCK(NULL, "lradc", lradc_clk)
|
||||
_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
|
||||
_REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk)
|
||||
_REGISTER_CLOCK("mxs-saif.0", NULL, saif0_clk)
|
||||
_REGISTER_CLOCK("mxs-saif.1", NULL, saif1_clk)
|
||||
};
|
||||
|
||||
static int clk_misc_init(void)
|
||||
{
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
/* Fix up parent per register setting */
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
|
||||
cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
|
||||
&ref_xtal_clk : &ref_cpu_clk;
|
||||
emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
|
||||
&ref_xtal_clk : &ref_emi_clk;
|
||||
ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
|
||||
&ref_xtal_clk : &ref_io0_clk;
|
||||
ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
|
||||
&ref_xtal_clk : &ref_io0_clk;
|
||||
ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
|
||||
&ref_xtal_clk : &ref_io1_clk;
|
||||
ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
|
||||
&ref_xtal_clk : &ref_io1_clk;
|
||||
lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
|
||||
&ref_xtal_clk : &ref_pix_clk;
|
||||
gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
|
||||
&ref_xtal_clk : &ref_gpmi_clk;
|
||||
saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
|
||||
&ref_xtal_clk : &pll0_clk;
|
||||
saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
|
||||
&ref_xtal_clk : &pll0_clk;
|
||||
|
||||
/* Use int div over frac when both are available */
|
||||
__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
|
||||
__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
|
||||
__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
|
||||
reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
|
||||
reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
|
||||
reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
|
||||
reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
|
||||
reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
|
||||
reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
|
||||
reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
|
||||
|
||||
/* SAIF has to use frac div for functional operation */
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
|
||||
reg |= BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
|
||||
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
|
||||
reg |= BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
|
||||
|
||||
/*
|
||||
* Set safe hbus clock divider. A divider of 3 ensure that
|
||||
* the Vddd voltage required for the cpu clock is sufficiently
|
||||
* high for the hbus clock.
|
||||
*/
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
|
||||
reg &= BM_CLKCTRL_HBUS_DIV;
|
||||
reg |= 3 << BP_CLKCTRL_HBUS_DIV;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
|
||||
|
||||
ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
|
||||
|
||||
/* Gate off cpu clock in WFI for power saving */
|
||||
__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
|
||||
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
|
||||
|
||||
/*
|
||||
* Extra fec clock setting
|
||||
* The DENX M28 uses an external clock source
|
||||
* and the clock output must not be enabled
|
||||
*/
|
||||
if (!machine_is_m28evk()) {
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
|
||||
reg &= ~BM_CLKCTRL_ENET_SLEEP;
|
||||
reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
|
||||
}
|
||||
|
||||
/*
|
||||
* 480 MHz seems too high to be ssp clock source directly,
|
||||
* so set frac0 to get a 288 MHz ref_io0.
|
||||
*/
|
||||
reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
|
||||
reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
|
||||
reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
|
||||
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __init mx28_clocks_init(void)
|
||||
{
|
||||
clk_misc_init();
|
||||
|
||||
/*
|
||||
* source ssp clock from ref_io0 than ref_xtal,
|
||||
* as ref_xtal only provides 24 MHz as maximum.
|
||||
*/
|
||||
clk_set_parent(&ssp0_clk, &ref_io0_clk);
|
||||
clk_set_parent(&ssp1_clk, &ref_io0_clk);
|
||||
clk_set_parent(&ssp2_clk, &ref_io1_clk);
|
||||
clk_set_parent(&ssp3_clk, &ref_io1_clk);
|
||||
|
||||
clk_prepare_enable(&cpu_clk);
|
||||
clk_prepare_enable(&hbus_clk);
|
||||
clk_prepare_enable(&xbus_clk);
|
||||
clk_prepare_enable(&emi_clk);
|
||||
clk_prepare_enable(&uart_clk);
|
||||
|
||||
clk_set_parent(&lcdif_clk, &ref_pix_clk);
|
||||
clk_set_parent(&saif0_clk, &pll0_clk);
|
||||
clk_set_parent(&saif1_clk, &pll0_clk);
|
||||
|
||||
/*
|
||||
* Set an initial clock rate for the saif internal logic to work
|
||||
* properly. This is important when working in EXTMASTER mode that
|
||||
* uses the other saif's BITCLK&LRCLK but it still needs a basic
|
||||
* clock which should be fast enough for the internal logic.
|
||||
*/
|
||||
clk_set_rate(&saif0_clk, 24000000);
|
||||
clk_set_rate(&saif1_clk, 24000000);
|
||||
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* Based on arch/arm/plat-omap/clock.c
|
||||
*
|
||||
* Copyright (C) 2004 - 2005 Nokia corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
* Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
|
||||
* Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2008 Juergen Beisert, 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, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <mach/clock.h>
|
||||
|
||||
static LIST_HEAD(clocks);
|
||||
static DEFINE_MUTEX(clocks_mutex);
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Standard clock functions defined in include/linux/clk.h
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
static void __clk_disable(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
WARN_ON(!clk->usecount);
|
||||
|
||||
if (!(--clk->usecount)) {
|
||||
if (clk->disable)
|
||||
clk->disable(clk);
|
||||
__clk_disable(clk->parent);
|
||||
}
|
||||
}
|
||||
|
||||
static int __clk_enable(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->usecount++ == 0) {
|
||||
__clk_enable(clk->parent);
|
||||
|
||||
if (clk->enable)
|
||||
clk->enable(clk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The clk_enable/clk_disable could be called by drivers in atomic context,
|
||||
* so they should not really hold mutex. Instead, clk_prepare/clk_unprepare
|
||||
* can hold a mutex, as the pair will only be called in non-atomic context.
|
||||
* Before migrating to common clk framework, we can have __clk_enable and
|
||||
* __clk_disable called in clk_prepare/clk_unprepare with mutex held and
|
||||
* leave clk_enable/clk_disable as the dummy functions.
|
||||
*/
|
||||
int clk_prepare(struct clk *clk)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
ret = __clk_enable(clk);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_prepare);
|
||||
|
||||
void clk_unprepare(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
__clk_disable(clk);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_unprepare);
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
/* Retrieve the *current* clock rate. If the clock itself
|
||||
* does not provide a special calculation routine, ask
|
||||
* its parent and so on, until one is able to return
|
||||
* a valid clock rate
|
||||
*/
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return 0UL;
|
||||
|
||||
if (clk->get_rate)
|
||||
return clk->get_rate(clk);
|
||||
|
||||
return clk_get_rate(clk->parent);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
/* Round the requested clock rate to the nearest supported
|
||||
* rate that is less than or equal to the requested rate.
|
||||
* This is dependent on the clock's current parent.
|
||||
*/
|
||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
|
||||
return 0;
|
||||
|
||||
return clk->round_rate(clk, rate);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_round_rate);
|
||||
|
||||
/* Set the clock to the requested clock rate. The rate must
|
||||
* match a supported rate exactly based on what clk_round_rate returns
|
||||
*/
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
ret = clk->set_rate(clk, rate);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_rate);
|
||||
|
||||
/* Set the clock's parent to another clock source */
|
||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct clk *old;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk) || parent == NULL ||
|
||||
IS_ERR(parent) || clk->set_parent == NULL)
|
||||
return ret;
|
||||
|
||||
if (clk->usecount)
|
||||
clk_prepare_enable(parent);
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
ret = clk->set_parent(clk, parent);
|
||||
if (ret == 0) {
|
||||
old = clk->parent;
|
||||
clk->parent = parent;
|
||||
} else {
|
||||
old = parent;
|
||||
}
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
if (clk->usecount)
|
||||
clk_disable(old);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_parent);
|
||||
|
||||
/* Retrieve the clock's parent clock source */
|
||||
struct clk *clk_get_parent(struct clk *clk)
|
||||
{
|
||||
struct clk *ret = NULL;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return ret;
|
||||
|
||||
return clk->parent;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_parent);
|
@ -1,6 +1,5 @@
|
||||
config MXS_HAVE_AMBA_DUART
|
||||
bool
|
||||
select ARM_AMBA
|
||||
|
||||
config MXS_HAVE_PLATFORM_AUART
|
||||
bool
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <mach/mx28.h>
|
||||
#include <mach/devices-common.h>
|
||||
|
||||
static struct platform_device *__init mxs_add_dma(const char *devid,
|
||||
struct platform_device *__init mxs_add_dma(const char *devid,
|
||||
resource_size_t base)
|
||||
{
|
||||
struct resource res[] = {
|
||||
@ -29,22 +29,3 @@ static struct platform_device *__init mxs_add_dma(const char *devid,
|
||||
res, ARRAY_SIZE(res), NULL, 0,
|
||||
DMA_BIT_MASK(32));
|
||||
}
|
||||
|
||||
static int __init mxs_add_mxs_dma(void)
|
||||
{
|
||||
char *apbh = "mxs-dma-apbh";
|
||||
char *apbx = "mxs-dma-apbx";
|
||||
|
||||
if (cpu_is_mx23()) {
|
||||
mxs_add_dma(apbh, MX23_APBH_DMA_BASE_ADDR);
|
||||
mxs_add_dma(apbx, MX23_APBX_DMA_BASE_ADDR);
|
||||
}
|
||||
|
||||
if (cpu_is_mx28()) {
|
||||
mxs_add_dma(apbh, MX28_APBH_DMA_BASE_ADDR);
|
||||
mxs_add_dma(apbx, MX28_APBX_DMA_BASE_ADDR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(mxs_add_mxs_dma);
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <mach/devices-common.h>
|
||||
|
||||
struct platform_device *__init mxs_add_gpio(
|
||||
int id, resource_size_t iobase, int irq)
|
||||
char *name, int id, resource_size_t iobase, int irq)
|
||||
{
|
||||
struct resource res[] = {
|
||||
{
|
||||
@ -29,25 +29,5 @@ struct platform_device *__init mxs_add_gpio(
|
||||
};
|
||||
|
||||
return platform_device_register_resndata(&mxs_apbh_bus,
|
||||
"gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0);
|
||||
name, id, res, ARRAY_SIZE(res), NULL, 0);
|
||||
}
|
||||
|
||||
static int __init mxs_add_mxs_gpio(void)
|
||||
{
|
||||
if (cpu_is_mx23()) {
|
||||
mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
|
||||
mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
|
||||
mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
|
||||
}
|
||||
|
||||
if (cpu_is_mx28()) {
|
||||
mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
|
||||
mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
|
||||
mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
|
||||
mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
|
||||
mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(mxs_add_mxs_gpio);
|
||||
|
@ -17,8 +17,9 @@
|
||||
#include <mach/mx28.h>
|
||||
#include <mach/devices-common.h>
|
||||
|
||||
#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \
|
||||
#define mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid) \
|
||||
{ \
|
||||
.devid = _devid, \
|
||||
.id = _id, \
|
||||
.iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \
|
||||
.dma = soc ## _DMA_SSP ## hwid, \
|
||||
@ -26,23 +27,23 @@
|
||||
.irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \
|
||||
}
|
||||
|
||||
#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \
|
||||
[_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid)
|
||||
#define mxs_mxs_mmc_data_entry(soc, _devid, _id, hwid) \
|
||||
[_id] = mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid)
|
||||
|
||||
|
||||
#ifdef CONFIG_SOC_IMX23
|
||||
const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
|
||||
mxs_mxs_mmc_data_entry(MX23, 0, 1),
|
||||
mxs_mxs_mmc_data_entry(MX23, 1, 2),
|
||||
mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 0, 1),
|
||||
mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 1, 2),
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_IMX28
|
||||
const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
|
||||
mxs_mxs_mmc_data_entry(MX28, 0, 0),
|
||||
mxs_mxs_mmc_data_entry(MX28, 1, 1),
|
||||
mxs_mxs_mmc_data_entry(MX28, 2, 2),
|
||||
mxs_mxs_mmc_data_entry(MX28, 3, 3),
|
||||
mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 0, 0),
|
||||
mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 1, 1),
|
||||
mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 2, 2),
|
||||
mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 3, 3),
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -70,6 +71,6 @@ struct platform_device *__init mxs_add_mxs_mmc(
|
||||
},
|
||||
};
|
||||
|
||||
return mxs_add_platform_device("mxs-mmc", data->id,
|
||||
return mxs_add_platform_device(data->devid, data->id,
|
||||
res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2008 Juergen Beisert, 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, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MXS_CLOCK_H__
|
||||
#define __MACH_MXS_CLOCK_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <linux/list.h>
|
||||
|
||||
struct module;
|
||||
|
||||
struct clk {
|
||||
int id;
|
||||
/* Source clock this clk depends on */
|
||||
struct clk *parent;
|
||||
/* Reference count of clock enable/disable */
|
||||
__s8 usecount;
|
||||
/* Register bit position for clock's enable/disable control. */
|
||||
u8 enable_shift;
|
||||
/* Register address for clock's enable/disable control. */
|
||||
void __iomem *enable_reg;
|
||||
u32 flags;
|
||||
/* get the current clock rate (always a fresh value) */
|
||||
unsigned long (*get_rate) (struct clk *);
|
||||
/* Function ptr to set the clock to a new rate. The rate must match a
|
||||
supported rate returned from round_rate. Leave blank if clock is not
|
||||
programmable */
|
||||
int (*set_rate) (struct clk *, unsigned long);
|
||||
/* Function ptr to round the requested clock rate to the nearest
|
||||
supported rate that is less than or equal to the requested rate. */
|
||||
unsigned long (*round_rate) (struct clk *, unsigned long);
|
||||
/* Function ptr to enable the clock. Leave blank if clock can not
|
||||
be gated. */
|
||||
int (*enable) (struct clk *);
|
||||
/* Function ptr to disable the clock. Leave blank if clock can not
|
||||
be gated. */
|
||||
void (*disable) (struct clk *);
|
||||
/* Function ptr to set the parent clock of the clock. */
|
||||
int (*set_parent) (struct clk *, struct clk *);
|
||||
};
|
||||
|
||||
int clk_register(struct clk *clk);
|
||||
void clk_unregister(struct clk *clk);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __MACH_MXS_CLOCK_H__ */
|
@ -11,26 +11,27 @@
|
||||
#ifndef __MACH_MXS_COMMON_H__
|
||||
#define __MACH_MXS_COMMON_H__
|
||||
|
||||
struct clk;
|
||||
|
||||
extern const u32 *mxs_get_ocotp(void);
|
||||
extern int mxs_reset_block(void __iomem *);
|
||||
extern void mxs_timer_init(struct clk *, int);
|
||||
extern void mxs_timer_init(int);
|
||||
extern void mxs_restart(char, const char *);
|
||||
extern int mxs_saif_clkmux_select(unsigned int clkmux);
|
||||
|
||||
extern int mx23_register_gpios(void);
|
||||
extern void mx23_soc_init(void);
|
||||
extern int mx23_clocks_init(void);
|
||||
extern void mx23_map_io(void);
|
||||
extern void mx23_init_irq(void);
|
||||
|
||||
extern int mx28_register_gpios(void);
|
||||
extern void mx28_soc_init(void);
|
||||
extern int mx28_clocks_init(void);
|
||||
extern void mx28_map_io(void);
|
||||
extern void mx28_init_irq(void);
|
||||
|
||||
extern void icoll_init_irq(void);
|
||||
|
||||
extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);
|
||||
extern struct platform_device *mxs_add_dma(const char *devid,
|
||||
resource_size_t base);
|
||||
extern struct platform_device *mxs_add_gpio(char *name, int id,
|
||||
resource_size_t iobase, int irq);
|
||||
|
||||
#endif /* __MACH_MXS_COMMON_H__ */
|
||||
|
@ -87,8 +87,9 @@ struct platform_device * __init mxs_add_mxs_i2c(
|
||||
const struct mxs_mxs_i2c_data *data);
|
||||
|
||||
/* mmc */
|
||||
#include <mach/mmc.h>
|
||||
#include <linux/mmc/mxs-mmc.h>
|
||||
struct mxs_mxs_mmc_data {
|
||||
const char *devid;
|
||||
int id;
|
||||
resource_size_t iobase;
|
||||
resource_size_t dma;
|
||||
|
@ -207,6 +207,8 @@ static int apx4devkit_phy_fixup(struct phy_device *phy)
|
||||
|
||||
static void __init apx4devkit_init(void)
|
||||
{
|
||||
mx28_soc_init();
|
||||
|
||||
mxs_iomux_setup_multiple_pads(apx4devkit_pads,
|
||||
ARRAY_SIZE(apx4devkit_pads));
|
||||
|
||||
|
@ -319,6 +319,8 @@ static struct mxs_mmc_platform_data m28evk_mmc_pdata[] __initdata = {
|
||||
|
||||
static void __init m28evk_init(void)
|
||||
{
|
||||
mx28_soc_init();
|
||||
|
||||
mxs_iomux_setup_multiple_pads(m28evk_pads, ARRAY_SIZE(m28evk_pads));
|
||||
|
||||
mx28_add_duart();
|
||||
|
@ -141,6 +141,8 @@ static void __init mx23evk_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mx23_soc_init();
|
||||
|
||||
mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
|
||||
|
||||
mx23_add_duart();
|
||||
|
@ -226,7 +226,7 @@ static void __init mx28evk_fec_reset(void)
|
||||
struct clk *clk;
|
||||
|
||||
/* Enable fec phy clock */
|
||||
clk = clk_get_sys("pll2", NULL);
|
||||
clk = clk_get_sys("enet_out", NULL);
|
||||
if (!IS_ERR(clk))
|
||||
clk_prepare_enable(clk);
|
||||
|
||||
@ -413,6 +413,8 @@ static void __init mx28evk_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mx28_soc_init();
|
||||
|
||||
mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
|
||||
|
||||
mx28_add_duart();
|
||||
|
121
arch/arm/mach-mxs/mach-mxs.c
Normal file
121
arch/arm/mach-mxs/mach-mxs.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
static int __init mxs_icoll_add_irq_domain(struct device_node *np,
|
||||
struct device_node *interrupt_parent)
|
||||
{
|
||||
irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init mxs_gpio_add_irq_domain(struct device_node *np,
|
||||
struct device_node *interrupt_parent)
|
||||
{
|
||||
static int gpio_irq_base = MXS_GPIO_IRQ_START;
|
||||
|
||||
irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
|
||||
gpio_irq_base += 32;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mxs_irq_match[] __initconst = {
|
||||
{ .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
|
||||
{ .compatible = "fsl,mxs-gpio", .data = mxs_gpio_add_irq_domain, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static void __init mxs_dt_init_irq(void)
|
||||
{
|
||||
icoll_init_irq();
|
||||
of_irq_init(mxs_irq_match);
|
||||
}
|
||||
|
||||
static void __init imx23_timer_init(void)
|
||||
{
|
||||
mx23_clocks_init();
|
||||
}
|
||||
|
||||
static struct sys_timer imx23_timer = {
|
||||
.init = imx23_timer_init,
|
||||
};
|
||||
|
||||
static void __init imx28_timer_init(void)
|
||||
{
|
||||
mx28_clocks_init();
|
||||
}
|
||||
|
||||
static struct sys_timer imx28_timer = {
|
||||
.init = imx28_timer_init,
|
||||
};
|
||||
|
||||
static void __init imx28_evk_init(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
/* Enable fec phy clock */
|
||||
clk = clk_get_sys("enet_out", NULL);
|
||||
if (!IS_ERR(clk))
|
||||
clk_prepare_enable(clk);
|
||||
}
|
||||
|
||||
static void __init mxs_machine_init(void)
|
||||
{
|
||||
if (of_machine_is_compatible("fsl,imx28-evk"))
|
||||
imx28_evk_init();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static const char *imx23_dt_compat[] __initdata = {
|
||||
"fsl,imx23-evk",
|
||||
"fsl,imx23",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *imx28_dt_compat[] __initdata = {
|
||||
"fsl,imx28-evk",
|
||||
"fsl,imx28",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
|
||||
.map_io = mx23_map_io,
|
||||
.init_irq = mxs_dt_init_irq,
|
||||
.timer = &imx23_timer,
|
||||
.init_machine = mxs_machine_init,
|
||||
.dt_compat = imx23_dt_compat,
|
||||
.restart = mxs_restart,
|
||||
MACHINE_END
|
||||
|
||||
DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)")
|
||||
.map_io = mx28_map_io,
|
||||
.init_irq = mxs_dt_init_irq,
|
||||
.timer = &imx28_timer,
|
||||
.init_machine = mxs_machine_init,
|
||||
.dt_compat = imx28_dt_compat,
|
||||
.restart = mxs_restart,
|
||||
MACHINE_END
|
@ -85,6 +85,8 @@ static void __init stmp378x_dvb_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mx23_soc_init();
|
||||
|
||||
mxs_iomux_setup_multiple_pads(stmp378x_dvb_pads,
|
||||
ARRAY_SIZE(stmp378x_dvb_pads));
|
||||
|
||||
|
@ -146,6 +146,8 @@ static struct mxs_mmc_platform_data tx28_mmc0_pdata __initdata = {
|
||||
|
||||
static void __init tx28_stk5v3_init(void)
|
||||
{
|
||||
mx28_soc_init();
|
||||
|
||||
mxs_iomux_setup_multiple_pads(tx28_stk5v3_pads,
|
||||
ARRAY_SIZE(tx28_stk5v3_pads));
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
@ -61,3 +62,29 @@ void __init mx28_init_irq(void)
|
||||
{
|
||||
icoll_init_irq();
|
||||
}
|
||||
|
||||
void __init mx23_soc_init(void)
|
||||
{
|
||||
pinctrl_provide_dummies();
|
||||
|
||||
mxs_add_dma("imx23-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
|
||||
mxs_add_dma("imx23-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
|
||||
|
||||
mxs_add_gpio("imx23-gpio", 0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
|
||||
mxs_add_gpio("imx23-gpio", 1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
|
||||
mxs_add_gpio("imx23-gpio", 2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
|
||||
}
|
||||
|
||||
void __init mx28_soc_init(void)
|
||||
{
|
||||
pinctrl_provide_dummies();
|
||||
|
||||
mxs_add_dma("imx28-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
|
||||
mxs_add_dma("imx28-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
|
||||
|
||||
mxs_add_gpio("imx28-gpio", 0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
|
||||
mxs_add_gpio("imx28-gpio", 1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
|
||||
mxs_add_gpio("imx28-gpio", 2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
|
||||
mxs_add_gpio("imx28-gpio", 3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
|
||||
mxs_add_gpio("imx28-gpio", 4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
|
||||
}
|
||||
|
@ -1,331 +0,0 @@
|
||||
/*
|
||||
* Freescale CLKCTRL Register Definitions
|
||||
*
|
||||
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
||||
* Copyright 2008-2010 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* This file is created by xml file. Don't Edit it.
|
||||
*
|
||||
* Xml Revision: 1.48
|
||||
* Template revision: 26195
|
||||
*/
|
||||
|
||||
#ifndef __REGS_CLKCTRL_MX23_H__
|
||||
#define __REGS_CLKCTRL_MX23_H__
|
||||
|
||||
|
||||
#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
|
||||
#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
|
||||
#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
|
||||
#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
|
||||
|
||||
#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
|
||||
#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
|
||||
#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
|
||||
(((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
|
||||
#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
|
||||
#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
|
||||
#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
|
||||
#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
|
||||
#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
|
||||
#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
|
||||
#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
|
||||
#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
|
||||
#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
|
||||
#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
|
||||
#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
|
||||
#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
|
||||
(((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
|
||||
#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
|
||||
#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
|
||||
#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
|
||||
#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
|
||||
#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
|
||||
|
||||
#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
|
||||
|
||||
#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
|
||||
#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
|
||||
#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
|
||||
#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
|
||||
#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
|
||||
|
||||
#define HW_CLKCTRL_CPU (0x00000020)
|
||||
#define HW_CLKCTRL_CPU_SET (0x00000024)
|
||||
#define HW_CLKCTRL_CPU_CLR (0x00000028)
|
||||
#define HW_CLKCTRL_CPU_TOG (0x0000002c)
|
||||
|
||||
#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
|
||||
#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
|
||||
#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
|
||||
#define BP_CLKCTRL_CPU_DIV_XTAL 16
|
||||
#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
|
||||
#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
|
||||
#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
|
||||
#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
|
||||
#define BP_CLKCTRL_CPU_DIV_CPU 0
|
||||
#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
|
||||
#define BF_CLKCTRL_CPU_DIV_CPU(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
|
||||
|
||||
#define HW_CLKCTRL_HBUS (0x00000030)
|
||||
#define HW_CLKCTRL_HBUS_SET (0x00000034)
|
||||
#define HW_CLKCTRL_HBUS_CLR (0x00000038)
|
||||
#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
|
||||
|
||||
#define BM_CLKCTRL_HBUS_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
|
||||
#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
|
||||
#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
|
||||
#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
|
||||
#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
|
||||
#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
|
||||
#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
|
||||
#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
|
||||
#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
|
||||
#define BP_CLKCTRL_HBUS_SLOW_DIV 16
|
||||
#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
|
||||
#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
|
||||
#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
|
||||
#define BP_CLKCTRL_HBUS_DIV 0
|
||||
#define BM_CLKCTRL_HBUS_DIV 0x0000001F
|
||||
#define BF_CLKCTRL_HBUS_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
|
||||
|
||||
#define HW_CLKCTRL_XBUS (0x00000040)
|
||||
|
||||
#define BM_CLKCTRL_XBUS_BUSY 0x80000000
|
||||
#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
|
||||
#define BP_CLKCTRL_XBUS_DIV 0
|
||||
#define BM_CLKCTRL_XBUS_DIV 0x000003FF
|
||||
#define BF_CLKCTRL_XBUS_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
|
||||
|
||||
#define HW_CLKCTRL_XTAL (0x00000050)
|
||||
#define HW_CLKCTRL_XTAL_SET (0x00000054)
|
||||
#define HW_CLKCTRL_XTAL_CLR (0x00000058)
|
||||
#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
|
||||
|
||||
#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
|
||||
#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
|
||||
#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
|
||||
#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
|
||||
#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
|
||||
#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
|
||||
#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
|
||||
#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
|
||||
#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
|
||||
#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
|
||||
#define BP_CLKCTRL_XTAL_DIV_UART 0
|
||||
#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
|
||||
#define BF_CLKCTRL_XTAL_DIV_UART(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
|
||||
|
||||
#define HW_CLKCTRL_PIX (0x00000060)
|
||||
|
||||
#define BP_CLKCTRL_PIX_CLKGATE 31
|
||||
#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_PIX_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
|
||||
#define BP_CLKCTRL_PIX_DIV 0
|
||||
#define BM_CLKCTRL_PIX_DIV 0x00000FFF
|
||||
#define BF_CLKCTRL_PIX_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_PIX_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SSP (0x00000070)
|
||||
|
||||
#define BP_CLKCTRL_SSP_CLKGATE 31
|
||||
#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SSP_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
|
||||
#define BP_CLKCTRL_SSP_DIV 0
|
||||
#define BM_CLKCTRL_SSP_DIV 0x000001FF
|
||||
#define BF_CLKCTRL_SSP_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SSP_DIV)
|
||||
|
||||
#define HW_CLKCTRL_GPMI (0x00000080)
|
||||
|
||||
#define BP_CLKCTRL_GPMI_CLKGATE 31
|
||||
#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_GPMI_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
|
||||
#define BP_CLKCTRL_GPMI_DIV 0
|
||||
#define BM_CLKCTRL_GPMI_DIV 0x000003FF
|
||||
#define BF_CLKCTRL_GPMI_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SPDIF (0x00000090)
|
||||
|
||||
#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
|
||||
|
||||
#define HW_CLKCTRL_EMI (0x000000a0)
|
||||
|
||||
#define BP_CLKCTRL_EMI_CLKGATE 31
|
||||
#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
|
||||
#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
|
||||
#define BP_CLKCTRL_EMI_DIV_XTAL 8
|
||||
#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
|
||||
#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
|
||||
(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
|
||||
#define BP_CLKCTRL_EMI_DIV_EMI 0
|
||||
#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
|
||||
#define BF_CLKCTRL_EMI_DIV_EMI(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
|
||||
|
||||
#define HW_CLKCTRL_IR (0x000000b0)
|
||||
|
||||
#define BM_CLKCTRL_IR_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
|
||||
#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
|
||||
#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
|
||||
#define BP_CLKCTRL_IR_IROV_DIV 16
|
||||
#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
|
||||
#define BF_CLKCTRL_IR_IROV_DIV(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
|
||||
#define BP_CLKCTRL_IR_IR_DIV 0
|
||||
#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
|
||||
#define BF_CLKCTRL_IR_IR_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SAIF (0x000000c0)
|
||||
|
||||
#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SAIF_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
|
||||
#define BP_CLKCTRL_SAIF_DIV 0
|
||||
#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
|
||||
#define BF_CLKCTRL_SAIF_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SAIF_DIV)
|
||||
|
||||
#define HW_CLKCTRL_TV (0x000000d0)
|
||||
|
||||
#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
|
||||
#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
|
||||
|
||||
#define HW_CLKCTRL_ETM (0x000000e0)
|
||||
|
||||
#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_ETM_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
|
||||
#define BP_CLKCTRL_ETM_DIV 0
|
||||
#define BM_CLKCTRL_ETM_DIV 0x0000003F
|
||||
#define BF_CLKCTRL_ETM_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_ETM_DIV)
|
||||
|
||||
#define HW_CLKCTRL_FRAC (0x000000f0)
|
||||
#define HW_CLKCTRL_FRAC_SET (0x000000f4)
|
||||
#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
|
||||
#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
|
||||
|
||||
#define BP_CLKCTRL_FRAC_CLKGATEIO 31
|
||||
#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
|
||||
#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
|
||||
#define BP_CLKCTRL_FRAC_IOFRAC 24
|
||||
#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
|
||||
#define BF_CLKCTRL_FRAC_IOFRAC(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
|
||||
#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
|
||||
#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
|
||||
#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
|
||||
#define BP_CLKCTRL_FRAC_PIXFRAC 16
|
||||
#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
|
||||
#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
|
||||
#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
|
||||
#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
|
||||
#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
|
||||
#define BP_CLKCTRL_FRAC_EMIFRAC 8
|
||||
#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
|
||||
#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
|
||||
(((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
|
||||
#define BP_CLKCTRL_FRAC_CLKGATECPU 7
|
||||
#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
|
||||
#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
|
||||
#define BP_CLKCTRL_FRAC_CPUFRAC 0
|
||||
#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
|
||||
#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
|
||||
|
||||
#define HW_CLKCTRL_FRAC1 (0x00000100)
|
||||
#define HW_CLKCTRL_FRAC1_SET (0x00000104)
|
||||
#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
|
||||
#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
|
||||
|
||||
#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
|
||||
#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
|
||||
|
||||
#define HW_CLKCTRL_CLKSEQ (0x00000110)
|
||||
#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
|
||||
#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
|
||||
#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
|
||||
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
|
||||
|
||||
#define HW_CLKCTRL_RESET (0x00000120)
|
||||
|
||||
#define BM_CLKCTRL_RESET_CHIP 0x00000002
|
||||
#define BM_CLKCTRL_RESET_DIG 0x00000001
|
||||
|
||||
#define HW_CLKCTRL_STATUS (0x00000130)
|
||||
|
||||
#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
|
||||
#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
|
||||
#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
|
||||
(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
|
||||
|
||||
#define HW_CLKCTRL_VERSION (0x00000140)
|
||||
|
||||
#define BP_CLKCTRL_VERSION_MAJOR 24
|
||||
#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
|
||||
#define BF_CLKCTRL_VERSION_MAJOR(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
|
||||
#define BP_CLKCTRL_VERSION_MINOR 16
|
||||
#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
|
||||
#define BF_CLKCTRL_VERSION_MINOR(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
|
||||
#define BP_CLKCTRL_VERSION_STEP 0
|
||||
#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
|
||||
#define BF_CLKCTRL_VERSION_STEP(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
|
||||
|
||||
#endif /* __REGS_CLKCTRL_MX23_H__ */
|
@ -1,486 +0,0 @@
|
||||
/*
|
||||
* Freescale CLKCTRL Register Definitions
|
||||
*
|
||||
* Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* This file is created by xml file. Don't Edit it.
|
||||
*
|
||||
* Xml Revision: 1.48
|
||||
* Template revision: 26195
|
||||
*/
|
||||
|
||||
#ifndef __REGS_CLKCTRL_MX28_H__
|
||||
#define __REGS_CLKCTRL_MX28_H__
|
||||
|
||||
#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
|
||||
#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
|
||||
#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
|
||||
#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
|
||||
|
||||
#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
|
||||
#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
|
||||
#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
|
||||
(((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
|
||||
#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
|
||||
#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
|
||||
#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
|
||||
#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
|
||||
#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
|
||||
#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
|
||||
#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
|
||||
#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
|
||||
#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
|
||||
#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
|
||||
#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
|
||||
#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
|
||||
(((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
|
||||
#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
|
||||
#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
|
||||
#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
|
||||
#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
|
||||
#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
|
||||
|
||||
#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
|
||||
|
||||
#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
|
||||
#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
|
||||
#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
|
||||
#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
|
||||
#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
|
||||
|
||||
#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
|
||||
#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
|
||||
#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
|
||||
#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
|
||||
|
||||
#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
|
||||
#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
|
||||
#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
|
||||
#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
|
||||
(((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
|
||||
#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
|
||||
#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
|
||||
#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
|
||||
#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
|
||||
#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
|
||||
#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
|
||||
#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
|
||||
#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
|
||||
#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
|
||||
#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
|
||||
#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
|
||||
#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
|
||||
(((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
|
||||
#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
|
||||
#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
|
||||
#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
|
||||
#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
|
||||
#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
|
||||
#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
|
||||
|
||||
#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
|
||||
|
||||
#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
|
||||
#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
|
||||
#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
|
||||
#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
|
||||
#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
|
||||
|
||||
#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
|
||||
#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
|
||||
#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
|
||||
#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
|
||||
|
||||
#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
|
||||
#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
|
||||
#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
|
||||
#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
|
||||
(((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
|
||||
#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
|
||||
#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
|
||||
#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
|
||||
#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
|
||||
#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
|
||||
|
||||
#define HW_CLKCTRL_CPU (0x00000050)
|
||||
#define HW_CLKCTRL_CPU_SET (0x00000054)
|
||||
#define HW_CLKCTRL_CPU_CLR (0x00000058)
|
||||
#define HW_CLKCTRL_CPU_TOG (0x0000005c)
|
||||
|
||||
#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
|
||||
#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
|
||||
#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
|
||||
#define BP_CLKCTRL_CPU_DIV_XTAL 16
|
||||
#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
|
||||
#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
|
||||
#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
|
||||
#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
|
||||
#define BP_CLKCTRL_CPU_DIV_CPU 0
|
||||
#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
|
||||
#define BF_CLKCTRL_CPU_DIV_CPU(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
|
||||
|
||||
#define HW_CLKCTRL_HBUS (0x00000060)
|
||||
#define HW_CLKCTRL_HBUS_SET (0x00000064)
|
||||
#define HW_CLKCTRL_HBUS_CLR (0x00000068)
|
||||
#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
|
||||
|
||||
#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
|
||||
#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
|
||||
#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
|
||||
#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
|
||||
#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
|
||||
#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
|
||||
#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
|
||||
#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
|
||||
#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
|
||||
#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
|
||||
#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
|
||||
#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
|
||||
#define BP_CLKCTRL_HBUS_SLOW_DIV 16
|
||||
#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
|
||||
#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
|
||||
#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
|
||||
#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
|
||||
#define BP_CLKCTRL_HBUS_DIV 0
|
||||
#define BM_CLKCTRL_HBUS_DIV 0x0000001F
|
||||
#define BF_CLKCTRL_HBUS_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
|
||||
|
||||
#define HW_CLKCTRL_XBUS (0x00000070)
|
||||
|
||||
#define BM_CLKCTRL_XBUS_BUSY 0x80000000
|
||||
#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
|
||||
#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
|
||||
#define BP_CLKCTRL_XBUS_DIV 0
|
||||
#define BM_CLKCTRL_XBUS_DIV 0x000003FF
|
||||
#define BF_CLKCTRL_XBUS_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
|
||||
|
||||
#define HW_CLKCTRL_XTAL (0x00000080)
|
||||
#define HW_CLKCTRL_XTAL_SET (0x00000084)
|
||||
#define HW_CLKCTRL_XTAL_CLR (0x00000088)
|
||||
#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
|
||||
|
||||
#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
|
||||
#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
|
||||
#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
|
||||
#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
|
||||
#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
|
||||
#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
|
||||
#define BP_CLKCTRL_XTAL_DIV_UART 0
|
||||
#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
|
||||
#define BF_CLKCTRL_XTAL_DIV_UART(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
|
||||
|
||||
#define HW_CLKCTRL_SSP0 (0x00000090)
|
||||
|
||||
#define BP_CLKCTRL_SSP0_CLKGATE 31
|
||||
#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SSP0_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
|
||||
#define BP_CLKCTRL_SSP0_DIV 0
|
||||
#define BM_CLKCTRL_SSP0_DIV 0x000001FF
|
||||
#define BF_CLKCTRL_SSP0_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SSP0_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SSP1 (0x000000a0)
|
||||
|
||||
#define BP_CLKCTRL_SSP1_CLKGATE 31
|
||||
#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SSP1_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
|
||||
#define BP_CLKCTRL_SSP1_DIV 0
|
||||
#define BM_CLKCTRL_SSP1_DIV 0x000001FF
|
||||
#define BF_CLKCTRL_SSP1_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SSP1_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SSP2 (0x000000b0)
|
||||
|
||||
#define BP_CLKCTRL_SSP2_CLKGATE 31
|
||||
#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SSP2_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
|
||||
#define BP_CLKCTRL_SSP2_DIV 0
|
||||
#define BM_CLKCTRL_SSP2_DIV 0x000001FF
|
||||
#define BF_CLKCTRL_SSP2_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SSP2_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SSP3 (0x000000c0)
|
||||
|
||||
#define BP_CLKCTRL_SSP3_CLKGATE 31
|
||||
#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SSP3_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
|
||||
#define BP_CLKCTRL_SSP3_DIV 0
|
||||
#define BM_CLKCTRL_SSP3_DIV 0x000001FF
|
||||
#define BF_CLKCTRL_SSP3_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SSP3_DIV)
|
||||
|
||||
#define HW_CLKCTRL_GPMI (0x000000d0)
|
||||
|
||||
#define BP_CLKCTRL_GPMI_CLKGATE 31
|
||||
#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_GPMI_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
|
||||
#define BP_CLKCTRL_GPMI_DIV 0
|
||||
#define BM_CLKCTRL_GPMI_DIV 0x000003FF
|
||||
#define BF_CLKCTRL_GPMI_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SPDIF (0x000000e0)
|
||||
|
||||
#define BP_CLKCTRL_SPDIF_CLKGATE 31
|
||||
#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
|
||||
|
||||
#define HW_CLKCTRL_EMI (0x000000f0)
|
||||
|
||||
#define BP_CLKCTRL_EMI_CLKGATE 31
|
||||
#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
|
||||
#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
|
||||
#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
|
||||
#define BP_CLKCTRL_EMI_DIV_XTAL 8
|
||||
#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
|
||||
#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
|
||||
(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
|
||||
#define BP_CLKCTRL_EMI_DIV_EMI 0
|
||||
#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
|
||||
#define BF_CLKCTRL_EMI_DIV_EMI(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
|
||||
|
||||
#define HW_CLKCTRL_SAIF0 (0x00000100)
|
||||
|
||||
#define BP_CLKCTRL_SAIF0_CLKGATE 31
|
||||
#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
|
||||
#define BP_CLKCTRL_SAIF0_DIV 0
|
||||
#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
|
||||
#define BF_CLKCTRL_SAIF0_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
|
||||
|
||||
#define HW_CLKCTRL_SAIF1 (0x00000110)
|
||||
|
||||
#define BP_CLKCTRL_SAIF1_CLKGATE 31
|
||||
#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
|
||||
#define BP_CLKCTRL_SAIF1_DIV 0
|
||||
#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
|
||||
#define BF_CLKCTRL_SAIF1_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
|
||||
|
||||
#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
|
||||
|
||||
#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
|
||||
#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
|
||||
#define BP_CLKCTRL_DIS_LCDIF_DIV 0
|
||||
#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
|
||||
#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
|
||||
|
||||
#define HW_CLKCTRL_ETM (0x00000130)
|
||||
|
||||
#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
|
||||
#define BM_CLKCTRL_ETM_BUSY 0x20000000
|
||||
#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
|
||||
#define BP_CLKCTRL_ETM_DIV 0
|
||||
#define BM_CLKCTRL_ETM_DIV 0x0000007F
|
||||
#define BF_CLKCTRL_ETM_DIV(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_ETM_DIV)
|
||||
|
||||
#define HW_CLKCTRL_ENET (0x00000140)
|
||||
|
||||
#define BM_CLKCTRL_ENET_SLEEP 0x80000000
|
||||
#define BP_CLKCTRL_ENET_DISABLE 30
|
||||
#define BM_CLKCTRL_ENET_DISABLE 0x40000000
|
||||
#define BM_CLKCTRL_ENET_STATUS 0x20000000
|
||||
#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
|
||||
#define BP_CLKCTRL_ENET_DIV_TIME 21
|
||||
#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
|
||||
#define BF_CLKCTRL_ENET_DIV_TIME(v) \
|
||||
(((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
|
||||
#define BM_CLKCTRL_ENET_BUSY 0x08000000
|
||||
#define BP_CLKCTRL_ENET_DIV 21
|
||||
#define BM_CLKCTRL_ENET_DIV 0x07E00000
|
||||
#define BF_CLKCTRL_ENET_DIV(v) \
|
||||
(((v) << 21) & BM_CLKCTRL_ENET_DIV)
|
||||
#define BP_CLKCTRL_ENET_TIME_SEL 19
|
||||
#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
|
||||
#define BF_CLKCTRL_ENET_TIME_SEL(v) \
|
||||
(((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
|
||||
#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
|
||||
#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
|
||||
#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
|
||||
#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
|
||||
#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
|
||||
#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
|
||||
#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
|
||||
|
||||
#define HW_CLKCTRL_HSADC (0x00000150)
|
||||
|
||||
#define BM_CLKCTRL_HSADC_RESETB 0x40000000
|
||||
#define BP_CLKCTRL_HSADC_FREQDIV 28
|
||||
#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
|
||||
#define BF_CLKCTRL_HSADC_FREQDIV(v) \
|
||||
(((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
|
||||
|
||||
#define HW_CLKCTRL_FLEXCAN (0x00000160)
|
||||
|
||||
#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
|
||||
#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
|
||||
#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
|
||||
#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
|
||||
#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
|
||||
#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
|
||||
|
||||
#define HW_CLKCTRL_FRAC0 (0x000001b0)
|
||||
#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
|
||||
#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
|
||||
#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
|
||||
|
||||
#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
|
||||
#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
|
||||
#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
|
||||
#define BP_CLKCTRL_FRAC0_IO0FRAC 24
|
||||
#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
|
||||
#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
|
||||
#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
|
||||
#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
|
||||
#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
|
||||
#define BP_CLKCTRL_FRAC0_IO1FRAC 16
|
||||
#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
|
||||
#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
|
||||
#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
|
||||
#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
|
||||
#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
|
||||
#define BP_CLKCTRL_FRAC0_EMIFRAC 8
|
||||
#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
|
||||
#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
|
||||
(((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
|
||||
#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
|
||||
#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
|
||||
#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
|
||||
#define BP_CLKCTRL_FRAC0_CPUFRAC 0
|
||||
#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
|
||||
#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
|
||||
|
||||
#define HW_CLKCTRL_FRAC1 (0x000001c0)
|
||||
#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
|
||||
#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
|
||||
#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
|
||||
|
||||
#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
|
||||
#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
|
||||
#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
|
||||
#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
|
||||
#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
|
||||
#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
|
||||
#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
|
||||
#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
|
||||
#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
|
||||
#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
|
||||
#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
|
||||
#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
|
||||
(((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
|
||||
#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
|
||||
#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
|
||||
#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
|
||||
#define BP_CLKCTRL_FRAC1_PIXFRAC 0
|
||||
#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
|
||||
#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
|
||||
|
||||
#define HW_CLKCTRL_CLKSEQ (0x000001d0)
|
||||
#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
|
||||
#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
|
||||
#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
|
||||
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
|
||||
#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
|
||||
#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
|
||||
#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
|
||||
|
||||
#define HW_CLKCTRL_RESET (0x000001e0)
|
||||
|
||||
#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
|
||||
#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
|
||||
#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
|
||||
#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
|
||||
#define BM_CLKCTRL_RESET_CHIP 0x00000002
|
||||
#define BM_CLKCTRL_RESET_DIG 0x00000001
|
||||
|
||||
#define HW_CLKCTRL_STATUS (0x000001f0)
|
||||
|
||||
#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
|
||||
#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
|
||||
#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
|
||||
(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
|
||||
|
||||
#define HW_CLKCTRL_VERSION (0x00000200)
|
||||
|
||||
#define BP_CLKCTRL_VERSION_MAJOR 24
|
||||
#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
|
||||
#define BF_CLKCTRL_VERSION_MAJOR(v) \
|
||||
(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
|
||||
#define BP_CLKCTRL_VERSION_MINOR 16
|
||||
#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
|
||||
#define BF_CLKCTRL_VERSION_MINOR(v) \
|
||||
(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
|
||||
#define BP_CLKCTRL_VERSION_STEP 0
|
||||
#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
|
||||
#define BF_CLKCTRL_VERSION_STEP(v) \
|
||||
(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
|
||||
|
||||
#endif /* __REGS_CLKCTRL_MX28_H__ */
|
@ -37,8 +37,6 @@
|
||||
#define MXS_MODULE_CLKGATE (1 << 30)
|
||||
#define MXS_MODULE_SFTRST (1 << 31)
|
||||
|
||||
#define CLKCTRL_TIMEOUT 10 /* 10 ms */
|
||||
|
||||
static void __iomem *mxs_clkctrl_reset_addr;
|
||||
|
||||
/*
|
||||
@ -139,17 +137,3 @@ error:
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
EXPORT_SYMBOL(mxs_reset_block);
|
||||
|
||||
int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
|
||||
{
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
|
||||
while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
|
||||
+ reg_offset) & mask) {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/clockchips.h>
|
||||
@ -243,8 +244,16 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init mxs_timer_init(struct clk *timer_clk, int irq)
|
||||
void __init mxs_timer_init(int irq)
|
||||
{
|
||||
struct clk *timer_clk;
|
||||
|
||||
timer_clk = clk_get_sys("timrot", NULL);
|
||||
if (IS_ERR(timer_clk)) {
|
||||
pr_err("%s: failed to get clk\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
clk_prepare_enable(timer_clk);
|
||||
|
||||
/*
|
||||
|
@ -2,3 +2,5 @@
|
||||
obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
|
||||
clk-mux.o clk-divider.o
|
||||
|
||||
obj-$(CONFIG_ARCH_MXS) += mxs/
|
||||
|
8
drivers/clk/mxs/Makefile
Normal file
8
drivers/clk/mxs/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Makefile for mxs specific clk
|
||||
#
|
||||
|
||||
obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o
|
||||
|
||||
obj-$(CONFIG_SOC_IMX23) += clk-imx23.o
|
||||
obj-$(CONFIG_SOC_IMX28) += clk-imx28.o
|
110
drivers/clk/mxs/clk-div.c
Normal file
110
drivers/clk/mxs/clk-div.c
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include "clk.h"
|
||||
|
||||
/**
|
||||
* struct clk_div - mxs integer divider clock
|
||||
* @divider: the parent class
|
||||
* @ops: pointer to clk_ops of parent class
|
||||
* @reg: register address
|
||||
* @busy: busy bit shift
|
||||
*
|
||||
* The mxs divider clock is a subclass of basic clk_divider with an
|
||||
* addtional busy bit.
|
||||
*/
|
||||
struct clk_div {
|
||||
struct clk_divider divider;
|
||||
const struct clk_ops *ops;
|
||||
void __iomem *reg;
|
||||
u8 busy;
|
||||
};
|
||||
|
||||
static inline struct clk_div *to_clk_div(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
|
||||
|
||||
return container_of(divider, struct clk_div, divider);
|
||||
}
|
||||
|
||||
static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_div *div = to_clk_div(hw);
|
||||
|
||||
return div->ops->recalc_rate(&div->divider.hw, parent_rate);
|
||||
}
|
||||
|
||||
static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct clk_div *div = to_clk_div(hw);
|
||||
|
||||
return div->ops->round_rate(&div->divider.hw, rate, prate);
|
||||
}
|
||||
|
||||
static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_div *div = to_clk_div(hw);
|
||||
int ret;
|
||||
|
||||
ret = div->ops->set_rate(&div->divider.hw, rate, parent_rate);
|
||||
if (!ret)
|
||||
ret = mxs_clk_wait(div->reg, div->busy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct clk_ops clk_div_ops = {
|
||||
.recalc_rate = clk_div_recalc_rate,
|
||||
.round_rate = clk_div_round_rate,
|
||||
.set_rate = clk_div_set_rate,
|
||||
};
|
||||
|
||||
struct clk *mxs_clk_div(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 shift, u8 width, u8 busy)
|
||||
{
|
||||
struct clk_div *div;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||
if (!div)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_div_ops;
|
||||
init.flags = CLK_SET_RATE_PARENT;
|
||||
init.parent_names = (parent_name ? &parent_name: NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
||||
div->reg = reg;
|
||||
div->busy = busy;
|
||||
|
||||
div->divider.reg = reg;
|
||||
div->divider.shift = shift;
|
||||
div->divider.width = width;
|
||||
div->divider.flags = CLK_DIVIDER_ONE_BASED;
|
||||
div->divider.lock = &mxs_lock;
|
||||
div->divider.hw.init = &init;
|
||||
div->ops = &clk_divider_ops;
|
||||
|
||||
clk = clk_register(NULL, &div->divider.hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(div);
|
||||
|
||||
return clk;
|
||||
}
|
139
drivers/clk/mxs/clk-frac.c
Normal file
139
drivers/clk/mxs/clk-frac.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include "clk.h"
|
||||
|
||||
/**
|
||||
* struct clk_frac - mxs fractional divider clock
|
||||
* @hw: clk_hw for the fractional divider clock
|
||||
* @reg: register address
|
||||
* @shift: the divider bit shift
|
||||
* @width: the divider bit width
|
||||
* @busy: busy bit shift
|
||||
*
|
||||
* The clock is an adjustable fractional divider with a busy bit to wait
|
||||
* when the divider is adjusted.
|
||||
*/
|
||||
struct clk_frac {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u8 busy;
|
||||
};
|
||||
|
||||
#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
|
||||
|
||||
static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_frac *frac = to_clk_frac(hw);
|
||||
u32 div;
|
||||
|
||||
div = readl_relaxed(frac->reg) >> frac->shift;
|
||||
div &= (1 << frac->width) - 1;
|
||||
|
||||
return (parent_rate >> frac->width) * div;
|
||||
}
|
||||
|
||||
static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct clk_frac *frac = to_clk_frac(hw);
|
||||
unsigned long parent_rate = *prate;
|
||||
u32 div;
|
||||
u64 tmp;
|
||||
|
||||
if (rate > parent_rate)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = rate;
|
||||
tmp <<= frac->width;
|
||||
do_div(tmp, parent_rate);
|
||||
div = tmp;
|
||||
|
||||
if (!div)
|
||||
return -EINVAL;
|
||||
|
||||
return (parent_rate >> frac->width) * div;
|
||||
}
|
||||
|
||||
static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_frac *frac = to_clk_frac(hw);
|
||||
unsigned long flags;
|
||||
u32 div, val;
|
||||
u64 tmp;
|
||||
|
||||
if (rate > parent_rate)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = rate;
|
||||
tmp <<= frac->width;
|
||||
do_div(tmp, parent_rate);
|
||||
div = tmp;
|
||||
|
||||
if (!div)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&mxs_lock, flags);
|
||||
|
||||
val = readl_relaxed(frac->reg);
|
||||
val &= ~(((1 << frac->width) - 1) << frac->shift);
|
||||
val |= div << frac->shift;
|
||||
writel_relaxed(val, frac->reg);
|
||||
|
||||
spin_unlock_irqrestore(&mxs_lock, flags);
|
||||
|
||||
return mxs_clk_wait(frac->reg, frac->busy);
|
||||
}
|
||||
|
||||
static struct clk_ops clk_frac_ops = {
|
||||
.recalc_rate = clk_frac_recalc_rate,
|
||||
.round_rate = clk_frac_round_rate,
|
||||
.set_rate = clk_frac_set_rate,
|
||||
};
|
||||
|
||||
struct clk *mxs_clk_frac(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 shift, u8 width, u8 busy)
|
||||
{
|
||||
struct clk_frac *frac;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
frac = kzalloc(sizeof(*frac), GFP_KERNEL);
|
||||
if (!frac)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_frac_ops;
|
||||
init.flags = CLK_SET_RATE_PARENT;
|
||||
init.parent_names = (parent_name ? &parent_name: NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
||||
frac->reg = reg;
|
||||
frac->shift = shift;
|
||||
frac->width = width;
|
||||
frac->busy = busy;
|
||||
frac->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &frac->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(frac);
|
||||
|
||||
return clk;
|
||||
}
|
205
drivers/clk/mxs/clk-imx23.c
Normal file
205
drivers/clk/mxs/clk-imx23.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/mx23.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define DIGCTRL MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
|
||||
#define CLKCTRL MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
|
||||
#define PLLCTRL0 (CLKCTRL + 0x0000)
|
||||
#define CPU (CLKCTRL + 0x0020)
|
||||
#define HBUS (CLKCTRL + 0x0030)
|
||||
#define XBUS (CLKCTRL + 0x0040)
|
||||
#define XTAL (CLKCTRL + 0x0050)
|
||||
#define PIX (CLKCTRL + 0x0060)
|
||||
#define SSP (CLKCTRL + 0x0070)
|
||||
#define GPMI (CLKCTRL + 0x0080)
|
||||
#define SPDIF (CLKCTRL + 0x0090)
|
||||
#define EMI (CLKCTRL + 0x00a0)
|
||||
#define SAIF (CLKCTRL + 0x00c0)
|
||||
#define TV (CLKCTRL + 0x00d0)
|
||||
#define ETM (CLKCTRL + 0x00e0)
|
||||
#define FRAC (CLKCTRL + 0x00f0)
|
||||
#define CLKSEQ (CLKCTRL + 0x0110)
|
||||
|
||||
#define BP_CPU_INTERRUPT_WAIT 12
|
||||
#define BP_CLKSEQ_BYPASS_SAIF 0
|
||||
#define BP_CLKSEQ_BYPASS_SSP 5
|
||||
#define BP_SAIF_DIV_FRAC_EN 16
|
||||
#define BP_FRAC_IOFRAC 24
|
||||
|
||||
static void __init clk_misc_init(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Gate off cpu clock in WFI for power saving */
|
||||
__mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
|
||||
|
||||
/* Clear BYPASS for SAIF */
|
||||
__mxs_clrl(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ);
|
||||
|
||||
/* SAIF has to use frac div for functional operation */
|
||||
val = readl_relaxed(SAIF);
|
||||
val |= 1 << BP_SAIF_DIV_FRAC_EN;
|
||||
writel_relaxed(val, SAIF);
|
||||
|
||||
/*
|
||||
* Source ssp clock from ref_io than ref_xtal,
|
||||
* as ref_xtal only provides 24 MHz as maximum.
|
||||
*/
|
||||
__mxs_clrl(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ);
|
||||
|
||||
/*
|
||||
* 480 MHz seems too high to be ssp clock source directly,
|
||||
* so set frac to get a 288 MHz ref_io.
|
||||
*/
|
||||
__mxs_clrl(0x3f << BP_FRAC_IOFRAC, FRAC);
|
||||
__mxs_setl(30 << BP_FRAC_IOFRAC, FRAC);
|
||||
}
|
||||
|
||||
static struct clk_lookup uart_lookups[] __initdata = {
|
||||
{ .dev_id = "duart", },
|
||||
{ .dev_id = "mxs-auart.0", },
|
||||
{ .dev_id = "mxs-auart.1", },
|
||||
{ .dev_id = "8006c000.serial", },
|
||||
{ .dev_id = "8006e000.serial", },
|
||||
{ .dev_id = "80070000.serial", },
|
||||
};
|
||||
|
||||
static struct clk_lookup hbus_lookups[] __initdata = {
|
||||
{ .dev_id = "imx23-dma-apbh", },
|
||||
{ .dev_id = "80004000.dma-apbh", },
|
||||
};
|
||||
|
||||
static struct clk_lookup xbus_lookups[] __initdata = {
|
||||
{ .dev_id = "duart", .con_id = "apb_pclk"},
|
||||
{ .dev_id = "80070000.serial", .con_id = "apb_pclk"},
|
||||
{ .dev_id = "imx23-dma-apbx", },
|
||||
{ .dev_id = "80024000.dma-apbx", },
|
||||
};
|
||||
|
||||
static struct clk_lookup ssp_lookups[] __initdata = {
|
||||
{ .dev_id = "imx23-mmc.0", },
|
||||
{ .dev_id = "imx23-mmc.1", },
|
||||
{ .dev_id = "80010000.ssp", },
|
||||
{ .dev_id = "80034000.ssp", },
|
||||
};
|
||||
|
||||
static struct clk_lookup lcdif_lookups[] __initdata = {
|
||||
{ .dev_id = "imx23-fb", },
|
||||
{ .dev_id = "80030000.lcdif", },
|
||||
};
|
||||
|
||||
static struct clk_lookup gpmi_lookups[] __initdata = {
|
||||
{ .dev_id = "imx23-gpmi-nand", },
|
||||
{ .dev_id = "8000c000.gpmi", },
|
||||
};
|
||||
|
||||
static const char *sel_pll[] __initconst = { "pll", "ref_xtal", };
|
||||
static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
|
||||
static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
|
||||
static const char *sel_io[] __initconst = { "ref_io", "ref_xtal", };
|
||||
static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
|
||||
static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
|
||||
|
||||
enum imx23_clk {
|
||||
ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
|
||||
lcdif_sel, gpmi_sel, ssp_sel, emi_sel, cpu, etm_sel, cpu_pll,
|
||||
cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll,
|
||||
emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div,
|
||||
clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif,
|
||||
lcdif, etm, usb, usb_pwr,
|
||||
clk_max
|
||||
};
|
||||
|
||||
static struct clk *clks[clk_max];
|
||||
|
||||
static enum imx23_clk clks_init_on[] __initdata = {
|
||||
cpu, hbus, xbus, emi, uart,
|
||||
};
|
||||
|
||||
int __init mx23_clocks_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
clk_misc_init();
|
||||
|
||||
clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
|
||||
clks[pll] = mxs_clk_pll("pll", "ref_xtal", PLLCTRL0, 16, 480000000);
|
||||
clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll", FRAC, 0);
|
||||
clks[ref_emi] = mxs_clk_ref("ref_emi", "pll", FRAC, 1);
|
||||
clks[ref_pix] = mxs_clk_ref("ref_pix", "pll", FRAC, 2);
|
||||
clks[ref_io] = mxs_clk_ref("ref_io", "pll", FRAC, 3);
|
||||
clks[saif_sel] = mxs_clk_mux("saif_sel", CLKSEQ, 0, 1, sel_pll, ARRAY_SIZE(sel_pll));
|
||||
clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 1, 1, sel_pix, ARRAY_SIZE(sel_pix));
|
||||
clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 4, 1, sel_io, ARRAY_SIZE(sel_io));
|
||||
clks[ssp_sel] = mxs_clk_mux("ssp_sel", CLKSEQ, 5, 1, sel_io, ARRAY_SIZE(sel_io));
|
||||
clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 6, 1, emi_sels, ARRAY_SIZE(emi_sels));
|
||||
clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 7, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
|
||||
clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
|
||||
clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
|
||||
clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
|
||||
clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 29);
|
||||
clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
|
||||
clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", PIX, 0, 12, 29);
|
||||
clks[ssp_div] = mxs_clk_div("ssp_div", "ssp_sel", SSP, 0, 9, 29);
|
||||
clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
|
||||
clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
|
||||
clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
|
||||
clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 6, 29);
|
||||
clks[saif_div] = mxs_clk_frac("saif_div", "saif_sel", SAIF, 0, 16, 29);
|
||||
clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
|
||||
clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
|
||||
clks[adc] = mxs_clk_fixed_factor("adc", "clk32k", 1, 16);
|
||||
clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll", 1, 4);
|
||||
clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
|
||||
clks[dri] = mxs_clk_gate("dri", "ref_xtal", XTAL, 28);
|
||||
clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
|
||||
clks[filt] = mxs_clk_gate("filt", "ref_xtal", XTAL, 30);
|
||||
clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
|
||||
clks[ssp] = mxs_clk_gate("ssp", "ssp_div", SSP, 31);
|
||||
clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
|
||||
clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
|
||||
clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
|
||||
clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31);
|
||||
clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31);
|
||||
clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
|
||||
clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2);
|
||||
clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks); i++)
|
||||
if (IS_ERR(clks[i])) {
|
||||
pr_err("i.MX23 clk %d: register failed with %ld\n",
|
||||
i, PTR_ERR(clks[i]));
|
||||
return PTR_ERR(clks[i]);
|
||||
}
|
||||
|
||||
clk_register_clkdev(clks[clk32k], NULL, "timrot");
|
||||
clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
|
||||
clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
|
||||
clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
|
||||
clk_register_clkdevs(clks[ssp], ssp_lookups, ARRAY_SIZE(ssp_lookups));
|
||||
clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
|
||||
clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
|
||||
clk_prepare_enable(clks[clks_init_on[i]]);
|
||||
|
||||
mxs_timer_init(MX23_INT_TIMER0);
|
||||
|
||||
return 0;
|
||||
}
|
338
drivers/clk/mxs/clk-imx28.c
Normal file
338
drivers/clk/mxs/clk-imx28.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/mx28.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define CLKCTRL MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
|
||||
#define PLL0CTRL0 (CLKCTRL + 0x0000)
|
||||
#define PLL1CTRL0 (CLKCTRL + 0x0020)
|
||||
#define PLL2CTRL0 (CLKCTRL + 0x0040)
|
||||
#define CPU (CLKCTRL + 0x0050)
|
||||
#define HBUS (CLKCTRL + 0x0060)
|
||||
#define XBUS (CLKCTRL + 0x0070)
|
||||
#define XTAL (CLKCTRL + 0x0080)
|
||||
#define SSP0 (CLKCTRL + 0x0090)
|
||||
#define SSP1 (CLKCTRL + 0x00a0)
|
||||
#define SSP2 (CLKCTRL + 0x00b0)
|
||||
#define SSP3 (CLKCTRL + 0x00c0)
|
||||
#define GPMI (CLKCTRL + 0x00d0)
|
||||
#define SPDIF (CLKCTRL + 0x00e0)
|
||||
#define EMI (CLKCTRL + 0x00f0)
|
||||
#define SAIF0 (CLKCTRL + 0x0100)
|
||||
#define SAIF1 (CLKCTRL + 0x0110)
|
||||
#define LCDIF (CLKCTRL + 0x0120)
|
||||
#define ETM (CLKCTRL + 0x0130)
|
||||
#define ENET (CLKCTRL + 0x0140)
|
||||
#define FLEXCAN (CLKCTRL + 0x0160)
|
||||
#define FRAC0 (CLKCTRL + 0x01b0)
|
||||
#define FRAC1 (CLKCTRL + 0x01c0)
|
||||
#define CLKSEQ (CLKCTRL + 0x01d0)
|
||||
|
||||
#define BP_CPU_INTERRUPT_WAIT 12
|
||||
#define BP_SAIF_DIV_FRAC_EN 16
|
||||
#define BP_ENET_DIV_TIME 21
|
||||
#define BP_ENET_SLEEP 31
|
||||
#define BP_CLKSEQ_BYPASS_SAIF0 0
|
||||
#define BP_CLKSEQ_BYPASS_SSP0 3
|
||||
#define BP_FRAC0_IO1FRAC 16
|
||||
#define BP_FRAC0_IO0FRAC 24
|
||||
|
||||
#define DIGCTRL MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
|
||||
#define BP_SAIF_CLKMUX 10
|
||||
|
||||
/*
|
||||
* HW_SAIF_CLKMUX_SEL:
|
||||
* DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
|
||||
* clock pins selected for SAIF1 input clocks.
|
||||
* CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
|
||||
* SAIF0 clock inputs selected for SAIF1 input clocks.
|
||||
* EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
|
||||
* clocks.
|
||||
* EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
|
||||
* clocks.
|
||||
*/
|
||||
int mxs_saif_clkmux_select(unsigned int clkmux)
|
||||
{
|
||||
if (clkmux > 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
__mxs_clrl(0x3 << BP_SAIF_CLKMUX, DIGCTRL);
|
||||
__mxs_setl(clkmux << BP_SAIF_CLKMUX, DIGCTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init clk_misc_init(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Gate off cpu clock in WFI for power saving */
|
||||
__mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
|
||||
|
||||
/* 0 is a bad default value for a divider */
|
||||
__mxs_setl(1 << BP_ENET_DIV_TIME, ENET);
|
||||
|
||||
/* Clear BYPASS for SAIF */
|
||||
__mxs_clrl(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ);
|
||||
|
||||
/* SAIF has to use frac div for functional operation */
|
||||
val = readl_relaxed(SAIF0);
|
||||
val |= 1 << BP_SAIF_DIV_FRAC_EN;
|
||||
writel_relaxed(val, SAIF0);
|
||||
|
||||
val = readl_relaxed(SAIF1);
|
||||
val |= 1 << BP_SAIF_DIV_FRAC_EN;
|
||||
writel_relaxed(val, SAIF1);
|
||||
|
||||
/* Extra fec clock setting */
|
||||
val = readl_relaxed(ENET);
|
||||
val &= ~(1 << BP_ENET_SLEEP);
|
||||
writel_relaxed(val, ENET);
|
||||
|
||||
/*
|
||||
* Source ssp clock from ref_io than ref_xtal,
|
||||
* as ref_xtal only provides 24 MHz as maximum.
|
||||
*/
|
||||
__mxs_clrl(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ);
|
||||
|
||||
/*
|
||||
* 480 MHz seems too high to be ssp clock source directly,
|
||||
* so set frac0 to get a 288 MHz ref_io0.
|
||||
*/
|
||||
val = readl_relaxed(FRAC0);
|
||||
val &= ~(0x3f << BP_FRAC0_IO0FRAC);
|
||||
val |= 30 << BP_FRAC0_IO0FRAC;
|
||||
writel_relaxed(val, FRAC0);
|
||||
}
|
||||
|
||||
static struct clk_lookup uart_lookups[] __initdata = {
|
||||
{ .dev_id = "duart", },
|
||||
{ .dev_id = "mxs-auart.0", },
|
||||
{ .dev_id = "mxs-auart.1", },
|
||||
{ .dev_id = "mxs-auart.2", },
|
||||
{ .dev_id = "mxs-auart.3", },
|
||||
{ .dev_id = "mxs-auart.4", },
|
||||
{ .dev_id = "8006a000.serial", },
|
||||
{ .dev_id = "8006c000.serial", },
|
||||
{ .dev_id = "8006e000.serial", },
|
||||
{ .dev_id = "80070000.serial", },
|
||||
{ .dev_id = "80072000.serial", },
|
||||
{ .dev_id = "80074000.serial", },
|
||||
};
|
||||
|
||||
static struct clk_lookup hbus_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-dma-apbh", },
|
||||
{ .dev_id = "80004000.dma-apbh", },
|
||||
};
|
||||
|
||||
static struct clk_lookup xbus_lookups[] __initdata = {
|
||||
{ .dev_id = "duart", .con_id = "apb_pclk"},
|
||||
{ .dev_id = "80074000.serial", .con_id = "apb_pclk"},
|
||||
{ .dev_id = "imx28-dma-apbx", },
|
||||
{ .dev_id = "80024000.dma-apbx", },
|
||||
};
|
||||
|
||||
static struct clk_lookup ssp0_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-mmc.0", },
|
||||
{ .dev_id = "80010000.ssp", },
|
||||
};
|
||||
|
||||
static struct clk_lookup ssp1_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-mmc.1", },
|
||||
{ .dev_id = "80012000.ssp", },
|
||||
};
|
||||
|
||||
static struct clk_lookup ssp2_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-mmc.2", },
|
||||
{ .dev_id = "80014000.ssp", },
|
||||
};
|
||||
|
||||
static struct clk_lookup ssp3_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-mmc.3", },
|
||||
{ .dev_id = "80016000.ssp", },
|
||||
};
|
||||
|
||||
static struct clk_lookup lcdif_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-fb", },
|
||||
{ .dev_id = "80030000.lcdif", },
|
||||
};
|
||||
|
||||
static struct clk_lookup gpmi_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-gpmi-nand", },
|
||||
{ .dev_id = "8000c000.gpmi", },
|
||||
};
|
||||
|
||||
static struct clk_lookup fec_lookups[] __initdata = {
|
||||
{ .dev_id = "imx28-fec.0", },
|
||||
{ .dev_id = "imx28-fec.1", },
|
||||
{ .dev_id = "800f0000.ethernet", },
|
||||
{ .dev_id = "800f4000.ethernet", },
|
||||
};
|
||||
|
||||
static struct clk_lookup can0_lookups[] __initdata = {
|
||||
{ .dev_id = "flexcan.0", },
|
||||
{ .dev_id = "80032000.can", },
|
||||
};
|
||||
|
||||
static struct clk_lookup can1_lookups[] __initdata = {
|
||||
{ .dev_id = "flexcan.1", },
|
||||
{ .dev_id = "80034000.can", },
|
||||
};
|
||||
|
||||
static struct clk_lookup saif0_lookups[] __initdata = {
|
||||
{ .dev_id = "mxs-saif.0", },
|
||||
{ .dev_id = "80042000.saif", },
|
||||
};
|
||||
|
||||
static struct clk_lookup saif1_lookups[] __initdata = {
|
||||
{ .dev_id = "mxs-saif.1", },
|
||||
{ .dev_id = "80046000.saif", },
|
||||
};
|
||||
|
||||
static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
|
||||
static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", };
|
||||
static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", };
|
||||
static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
|
||||
static const char *sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", };
|
||||
static const char *sel_pll0[] __initconst = { "pll0", "ref_xtal", };
|
||||
static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
|
||||
static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
|
||||
static const char *ptp_sels[] __initconst = { "ref_xtal", "pll0", };
|
||||
|
||||
enum imx28_clk {
|
||||
ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
|
||||
ref_pix, ref_hsadc, ref_gpmi, saif0_sel, saif1_sel, gpmi_sel,
|
||||
ssp0_sel, ssp1_sel, ssp2_sel, ssp3_sel, emi_sel, etm_sel,
|
||||
lcdif_sel, cpu, ptp_sel, cpu_pll, cpu_xtal, hbus, xbus,
|
||||
ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
|
||||
emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
|
||||
clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
|
||||
ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
|
||||
fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
|
||||
clk_max
|
||||
};
|
||||
|
||||
static struct clk *clks[clk_max];
|
||||
|
||||
static enum imx28_clk clks_init_on[] __initdata = {
|
||||
cpu, hbus, xbus, emi, uart,
|
||||
};
|
||||
|
||||
int __init mx28_clocks_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
clk_misc_init();
|
||||
|
||||
clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
|
||||
clks[pll0] = mxs_clk_pll("pll0", "ref_xtal", PLL0CTRL0, 17, 480000000);
|
||||
clks[pll1] = mxs_clk_pll("pll1", "ref_xtal", PLL1CTRL0, 17, 480000000);
|
||||
clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000);
|
||||
clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0);
|
||||
clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1);
|
||||
clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2);
|
||||
clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3);
|
||||
clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0);
|
||||
clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1);
|
||||
clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2);
|
||||
clks[saif0_sel] = mxs_clk_mux("saif0_sel", CLKSEQ, 0, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
|
||||
clks[saif1_sel] = mxs_clk_mux("saif1_sel", CLKSEQ, 1, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
|
||||
clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 2, 1, sel_gpmi, ARRAY_SIZE(sel_gpmi));
|
||||
clks[ssp0_sel] = mxs_clk_mux("ssp0_sel", CLKSEQ, 3, 1, sel_io0, ARRAY_SIZE(sel_io0));
|
||||
clks[ssp1_sel] = mxs_clk_mux("ssp1_sel", CLKSEQ, 4, 1, sel_io0, ARRAY_SIZE(sel_io0));
|
||||
clks[ssp2_sel] = mxs_clk_mux("ssp2_sel", CLKSEQ, 5, 1, sel_io1, ARRAY_SIZE(sel_io1));
|
||||
clks[ssp3_sel] = mxs_clk_mux("ssp3_sel", CLKSEQ, 6, 1, sel_io1, ARRAY_SIZE(sel_io1));
|
||||
clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 7, 1, emi_sels, ARRAY_SIZE(emi_sels));
|
||||
clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
|
||||
clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 14, 1, sel_pix, ARRAY_SIZE(sel_pix));
|
||||
clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 18, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
|
||||
clks[ptp_sel] = mxs_clk_mux("ptp_sel", ENET, 19, 1, ptp_sels, ARRAY_SIZE(ptp_sels));
|
||||
clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
|
||||
clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
|
||||
clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 31);
|
||||
clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
|
||||
clks[ssp0_div] = mxs_clk_div("ssp0_div", "ssp0_sel", SSP0, 0, 9, 29);
|
||||
clks[ssp1_div] = mxs_clk_div("ssp1_div", "ssp1_sel", SSP1, 0, 9, 29);
|
||||
clks[ssp2_div] = mxs_clk_div("ssp2_div", "ssp2_sel", SSP2, 0, 9, 29);
|
||||
clks[ssp3_div] = mxs_clk_div("ssp3_div", "ssp3_sel", SSP3, 0, 9, 29);
|
||||
clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
|
||||
clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
|
||||
clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
|
||||
clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", LCDIF, 0, 13, 29);
|
||||
clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 7, 29);
|
||||
clks[ptp] = mxs_clk_div("ptp", "ptp_sel", ENET, 21, 6, 27);
|
||||
clks[saif0_div] = mxs_clk_frac("saif0_div", "saif0_sel", SAIF0, 0, 16, 29);
|
||||
clks[saif1_div] = mxs_clk_frac("saif1_div", "saif1_sel", SAIF1, 0, 16, 29);
|
||||
clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
|
||||
clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
|
||||
clks[lradc] = mxs_clk_fixed_factor("lradc", "clk32k", 1, 16);
|
||||
clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll0", 1, 4);
|
||||
clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
|
||||
clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
|
||||
clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
|
||||
clks[ssp0] = mxs_clk_gate("ssp0", "ssp0_div", SSP0, 31);
|
||||
clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
|
||||
clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
|
||||
clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
|
||||
clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
|
||||
clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
|
||||
clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
|
||||
clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);
|
||||
clks[saif1] = mxs_clk_gate("saif1", "saif1_div", SAIF1, 31);
|
||||
clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", LCDIF, 31);
|
||||
clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
|
||||
clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30);
|
||||
clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30);
|
||||
clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28);
|
||||
clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2);
|
||||
clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16);
|
||||
clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock);
|
||||
clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock);
|
||||
clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks); i++)
|
||||
if (IS_ERR(clks[i])) {
|
||||
pr_err("i.MX28 clk %d: register failed with %ld\n",
|
||||
i, PTR_ERR(clks[i]));
|
||||
return PTR_ERR(clks[i]);
|
||||
}
|
||||
|
||||
clk_register_clkdev(clks[clk32k], NULL, "timrot");
|
||||
clk_register_clkdev(clks[enet_out], NULL, "enet_out");
|
||||
clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
|
||||
clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
|
||||
clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
|
||||
clk_register_clkdevs(clks[ssp0], ssp0_lookups, ARRAY_SIZE(ssp0_lookups));
|
||||
clk_register_clkdevs(clks[ssp1], ssp1_lookups, ARRAY_SIZE(ssp1_lookups));
|
||||
clk_register_clkdevs(clks[ssp2], ssp2_lookups, ARRAY_SIZE(ssp2_lookups));
|
||||
clk_register_clkdevs(clks[ssp3], ssp3_lookups, ARRAY_SIZE(ssp3_lookups));
|
||||
clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
|
||||
clk_register_clkdevs(clks[saif0], saif0_lookups, ARRAY_SIZE(saif0_lookups));
|
||||
clk_register_clkdevs(clks[saif1], saif1_lookups, ARRAY_SIZE(saif1_lookups));
|
||||
clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
|
||||
clk_register_clkdevs(clks[fec], fec_lookups, ARRAY_SIZE(fec_lookups));
|
||||
clk_register_clkdevs(clks[can0], can0_lookups, ARRAY_SIZE(can0_lookups));
|
||||
clk_register_clkdevs(clks[can1], can1_lookups, ARRAY_SIZE(can1_lookups));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
|
||||
clk_prepare_enable(clks[clks_init_on[i]]);
|
||||
|
||||
mxs_timer_init(MX28_INT_TIMER0);
|
||||
|
||||
return 0;
|
||||
}
|
116
drivers/clk/mxs/clk-pll.c
Normal file
116
drivers/clk/mxs/clk-pll.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include "clk.h"
|
||||
|
||||
/**
|
||||
* struct clk_pll - mxs pll clock
|
||||
* @hw: clk_hw for the pll
|
||||
* @base: base address of the pll
|
||||
* @power: the shift of power bit
|
||||
* @rate: the clock rate of the pll
|
||||
*
|
||||
* The mxs pll is a fixed rate clock with power and gate control,
|
||||
* and the shift of gate bit is always 31.
|
||||
*/
|
||||
struct clk_pll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
u8 power;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
|
||||
|
||||
static int clk_pll_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
|
||||
writel_relaxed(1 << pll->power, pll->base + SET);
|
||||
|
||||
udelay(10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_pll_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
|
||||
writel_relaxed(1 << pll->power, pll->base + CLR);
|
||||
}
|
||||
|
||||
static int clk_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
|
||||
writel_relaxed(1 << 31, pll->base + CLR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
|
||||
writel_relaxed(1 << 31, pll->base + SET);
|
||||
}
|
||||
|
||||
static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
|
||||
return pll->rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pll_ops = {
|
||||
.prepare = clk_pll_prepare,
|
||||
.unprepare = clk_pll_unprepare,
|
||||
.enable = clk_pll_enable,
|
||||
.disable = clk_pll_disable,
|
||||
.recalc_rate = clk_pll_recalc_rate,
|
||||
};
|
||||
|
||||
struct clk *mxs_clk_pll(const char *name, const char *parent_name,
|
||||
void __iomem *base, u8 power, unsigned long rate)
|
||||
{
|
||||
struct clk_pll *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_pll_ops;
|
||||
init.flags = 0;
|
||||
init.parent_names = (parent_name ? &parent_name: NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
||||
pll->base = base;
|
||||
pll->rate = rate;
|
||||
pll->power = power;
|
||||
pll->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(pll);
|
||||
|
||||
return clk;
|
||||
}
|
154
drivers/clk/mxs/clk-ref.c
Normal file
154
drivers/clk/mxs/clk-ref.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include "clk.h"
|
||||
|
||||
/**
|
||||
* struct clk_ref - mxs reference clock
|
||||
* @hw: clk_hw for the reference clock
|
||||
* @reg: register address
|
||||
* @idx: the index of the reference clock within the same register
|
||||
*
|
||||
* The mxs reference clock sources from pll. Every 4 reference clocks share
|
||||
* one register space, and @idx is used to identify them. Each reference
|
||||
* clock has a gate control and a fractional * divider. The rate is calculated
|
||||
* as pll rate * (18 / FRAC), where FRAC = 18 ~ 35.
|
||||
*/
|
||||
struct clk_ref {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
u8 idx;
|
||||
};
|
||||
|
||||
#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, hw)
|
||||
|
||||
static int clk_ref_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_ref *ref = to_clk_ref(hw);
|
||||
|
||||
writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + CLR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_ref_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_ref *ref = to_clk_ref(hw);
|
||||
|
||||
writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + SET);
|
||||
}
|
||||
|
||||
static unsigned long clk_ref_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_ref *ref = to_clk_ref(hw);
|
||||
u64 tmp = parent_rate;
|
||||
u8 frac = (readl_relaxed(ref->reg) >> (ref->idx * 8)) & 0x3f;
|
||||
|
||||
tmp *= 18;
|
||||
do_div(tmp, frac);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
unsigned long parent_rate = *prate;
|
||||
u64 tmp = parent_rate;
|
||||
u8 frac;
|
||||
|
||||
tmp = tmp * 18 + rate / 2;
|
||||
do_div(tmp, rate);
|
||||
frac = tmp;
|
||||
|
||||
if (frac < 18)
|
||||
frac = 18;
|
||||
else if (frac > 35)
|
||||
frac = 35;
|
||||
|
||||
tmp = parent_rate;
|
||||
tmp *= 18;
|
||||
do_div(tmp, frac);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_ref *ref = to_clk_ref(hw);
|
||||
unsigned long flags;
|
||||
u64 tmp = parent_rate;
|
||||
u32 val;
|
||||
u8 frac, shift = ref->idx * 8;
|
||||
|
||||
tmp = tmp * 18 + rate / 2;
|
||||
do_div(tmp, rate);
|
||||
frac = tmp;
|
||||
|
||||
if (frac < 18)
|
||||
frac = 18;
|
||||
else if (frac > 35)
|
||||
frac = 35;
|
||||
|
||||
spin_lock_irqsave(&mxs_lock, flags);
|
||||
|
||||
val = readl_relaxed(ref->reg);
|
||||
val &= ~(0x3f << shift);
|
||||
val |= frac << shift;
|
||||
writel_relaxed(val, ref->reg);
|
||||
|
||||
spin_unlock_irqrestore(&mxs_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_ref_ops = {
|
||||
.enable = clk_ref_enable,
|
||||
.disable = clk_ref_disable,
|
||||
.recalc_rate = clk_ref_recalc_rate,
|
||||
.round_rate = clk_ref_round_rate,
|
||||
.set_rate = clk_ref_set_rate,
|
||||
};
|
||||
|
||||
struct clk *mxs_clk_ref(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx)
|
||||
{
|
||||
struct clk_ref *ref;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
ref = kzalloc(sizeof(*ref), GFP_KERNEL);
|
||||
if (!ref)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_ref_ops;
|
||||
init.flags = 0;
|
||||
init.parent_names = (parent_name ? &parent_name: NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
||||
ref->reg = reg;
|
||||
ref->idx = idx;
|
||||
ref->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &ref->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(ref);
|
||||
|
||||
return clk;
|
||||
}
|
28
drivers/clk/mxs/clk.c
Normal file
28
drivers/clk/mxs/clk.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
DEFINE_SPINLOCK(mxs_lock);
|
||||
|
||||
int mxs_clk_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;
|
||||
}
|
66
drivers/clk/mxs/clk.h
Normal file
66
drivers/clk/mxs/clk.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __MXS_CLK_H
|
||||
#define __MXS_CLK_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define SET 0x4
|
||||
#define CLR 0x8
|
||||
|
||||
extern spinlock_t mxs_lock;
|
||||
|
||||
int mxs_clk_wait(void __iomem *reg, u8 shift);
|
||||
|
||||
struct clk *mxs_clk_pll(const char *name, const char *parent_name,
|
||||
void __iomem *base, u8 power, unsigned long rate);
|
||||
|
||||
struct clk *mxs_clk_ref(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx);
|
||||
|
||||
struct clk *mxs_clk_div(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 shift, u8 width, u8 busy);
|
||||
|
||||
struct clk *mxs_clk_frac(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 shift, u8 width, u8 busy);
|
||||
|
||||
static inline struct clk *mxs_clk_fixed(const char *name, int rate)
|
||||
{
|
||||
return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
|
||||
}
|
||||
|
||||
static inline struct clk *mxs_clk_gate(const char *name,
|
||||
const char *parent_name, void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_register_gate(NULL, name, parent_name, CLK_SET_RATE_PARENT,
|
||||
reg, shift, CLK_GATE_SET_TO_DISABLE,
|
||||
&mxs_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char **parent_names, int num_parents)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parent_names, num_parents,
|
||||
CLK_SET_RATE_PARENT, reg, shift, width,
|
||||
0, &mxs_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *mxs_clk_fixed_factor(const char *name,
|
||||
const char *parent_name, unsigned int mult, unsigned int div)
|
||||
{
|
||||
return clk_register_fixed_factor(NULL, name, parent_name,
|
||||
CLK_SET_RATE_PARENT, mult, div);
|
||||
}
|
||||
|
||||
#endif /* __MXS_CLK_H */
|
@ -238,6 +238,7 @@ config IMX_DMA
|
||||
config MXS_DMA
|
||||
bool "MXS DMA support"
|
||||
depends on SOC_IMX23 || SOC_IMX28
|
||||
select STMP_DEVICE
|
||||
select DMA_ENGINE
|
||||
help
|
||||
Support the MXS DMA engine. This engine including APBH-DMA
|
||||
|
@ -22,11 +22,14 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fsl/mxs-dma.h>
|
||||
#include <linux/stmp_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <mach/mxs.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#include "dmaengine.h"
|
||||
|
||||
@ -36,12 +39,8 @@
|
||||
* dma can program the controller registers of peripheral devices.
|
||||
*/
|
||||
|
||||
#define MXS_DMA_APBH 0
|
||||
#define MXS_DMA_APBX 1
|
||||
#define dma_is_apbh() (mxs_dma->dev_id == MXS_DMA_APBH)
|
||||
|
||||
#define APBH_VERSION_LATEST 3
|
||||
#define apbh_is_old() (mxs_dma->version < APBH_VERSION_LATEST)
|
||||
#define dma_is_apbh(mxs_dma) ((mxs_dma)->type == MXS_DMA_APBH)
|
||||
#define apbh_is_old(mxs_dma) ((mxs_dma)->dev_id == IMX23_DMA)
|
||||
|
||||
#define HW_APBHX_CTRL0 0x000
|
||||
#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
|
||||
@ -51,13 +50,14 @@
|
||||
#define HW_APBHX_CTRL2 0x020
|
||||
#define HW_APBHX_CHANNEL_CTRL 0x030
|
||||
#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16
|
||||
#define HW_APBH_VERSION (cpu_is_mx23() ? 0x3f0 : 0x800)
|
||||
#define HW_APBX_VERSION 0x800
|
||||
#define BP_APBHX_VERSION_MAJOR 24
|
||||
#define HW_APBHX_CHn_NXTCMDAR(n) \
|
||||
(((dma_is_apbh() && apbh_is_old()) ? 0x050 : 0x110) + (n) * 0x70)
|
||||
#define HW_APBHX_CHn_SEMA(n) \
|
||||
(((dma_is_apbh() && apbh_is_old()) ? 0x080 : 0x140) + (n) * 0x70)
|
||||
/*
|
||||
* The offset of NXTCMDAR register is different per both dma type and version,
|
||||
* while stride for each channel is all the same 0x70.
|
||||
*/
|
||||
#define HW_APBHX_CHn_NXTCMDAR(d, n) \
|
||||
(((dma_is_apbh(d) && apbh_is_old(d)) ? 0x050 : 0x110) + (n) * 0x70)
|
||||
#define HW_APBHX_CHn_SEMA(d, n) \
|
||||
(((dma_is_apbh(d) && apbh_is_old(d)) ? 0x080 : 0x140) + (n) * 0x70)
|
||||
|
||||
/*
|
||||
* ccw bits definitions
|
||||
@ -121,9 +121,19 @@ struct mxs_dma_chan {
|
||||
#define MXS_DMA_CHANNELS 16
|
||||
#define MXS_DMA_CHANNELS_MASK 0xffff
|
||||
|
||||
enum mxs_dma_devtype {
|
||||
MXS_DMA_APBH,
|
||||
MXS_DMA_APBX,
|
||||
};
|
||||
|
||||
enum mxs_dma_id {
|
||||
IMX23_DMA,
|
||||
IMX28_DMA,
|
||||
};
|
||||
|
||||
struct mxs_dma_engine {
|
||||
int dev_id;
|
||||
unsigned int version;
|
||||
enum mxs_dma_id dev_id;
|
||||
enum mxs_dma_devtype type;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
struct dma_device dma_device;
|
||||
@ -131,17 +141,86 @@ struct mxs_dma_engine {
|
||||
struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
|
||||
};
|
||||
|
||||
struct mxs_dma_type {
|
||||
enum mxs_dma_id id;
|
||||
enum mxs_dma_devtype type;
|
||||
};
|
||||
|
||||
static struct mxs_dma_type mxs_dma_types[] = {
|
||||
{
|
||||
.id = IMX23_DMA,
|
||||
.type = MXS_DMA_APBH,
|
||||
}, {
|
||||
.id = IMX23_DMA,
|
||||
.type = MXS_DMA_APBX,
|
||||
}, {
|
||||
.id = IMX28_DMA,
|
||||
.type = MXS_DMA_APBH,
|
||||
}, {
|
||||
.id = IMX28_DMA,
|
||||
.type = MXS_DMA_APBX,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device_id mxs_dma_ids[] = {
|
||||
{
|
||||
.name = "imx23-dma-apbh",
|
||||
.driver_data = (kernel_ulong_t) &mxs_dma_types[0],
|
||||
}, {
|
||||
.name = "imx23-dma-apbx",
|
||||
.driver_data = (kernel_ulong_t) &mxs_dma_types[1],
|
||||
}, {
|
||||
.name = "imx28-dma-apbh",
|
||||
.driver_data = (kernel_ulong_t) &mxs_dma_types[2],
|
||||
}, {
|
||||
.name = "imx28-dma-apbx",
|
||||
.driver_data = (kernel_ulong_t) &mxs_dma_types[3],
|
||||
}, {
|
||||
/* end of list */
|
||||
}
|
||||
};
|
||||
|
||||
static const struct of_device_id mxs_dma_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx23-dma-apbh", .data = &mxs_dma_ids[0], },
|
||||
{ .compatible = "fsl,imx23-dma-apbx", .data = &mxs_dma_ids[1], },
|
||||
{ .compatible = "fsl,imx28-dma-apbh", .data = &mxs_dma_ids[2], },
|
||||
{ .compatible = "fsl,imx28-dma-apbx", .data = &mxs_dma_ids[3], },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_dma_dt_ids);
|
||||
|
||||
static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
|
||||
{
|
||||
return container_of(chan, struct mxs_dma_chan, chan);
|
||||
}
|
||||
|
||||
int mxs_dma_is_apbh(struct dma_chan *chan)
|
||||
{
|
||||
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
|
||||
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
|
||||
|
||||
return dma_is_apbh(mxs_dma);
|
||||
}
|
||||
|
||||
int mxs_dma_is_apbx(struct dma_chan *chan)
|
||||
{
|
||||
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
|
||||
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
|
||||
|
||||
return !dma_is_apbh(mxs_dma);
|
||||
}
|
||||
|
||||
static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
|
||||
{
|
||||
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
|
||||
int chan_id = mxs_chan->chan.chan_id;
|
||||
|
||||
if (dma_is_apbh() && apbh_is_old())
|
||||
if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
|
||||
writel(1 << (chan_id + BP_APBH_CTRL0_RESET_CHANNEL),
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
|
||||
else
|
||||
writel(1 << (chan_id + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL),
|
||||
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
|
||||
}
|
||||
|
||||
static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
|
||||
@ -151,10 +230,10 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
|
||||
|
||||
/* set cmd_addr up */
|
||||
writel(mxs_chan->ccw_phys,
|
||||
mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id));
|
||||
mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(mxs_dma, chan_id));
|
||||
|
||||
/* write 1 to SEMA to kick off the channel */
|
||||
writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id));
|
||||
writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(mxs_dma, chan_id));
|
||||
}
|
||||
|
||||
static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
|
||||
@ -168,12 +247,12 @@ static void mxs_dma_pause_chan(struct mxs_dma_chan *mxs_chan)
|
||||
int chan_id = mxs_chan->chan.chan_id;
|
||||
|
||||
/* freeze the channel */
|
||||
if (dma_is_apbh() && apbh_is_old())
|
||||
if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
|
||||
writel(1 << chan_id,
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
|
||||
else
|
||||
writel(1 << chan_id,
|
||||
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
|
||||
|
||||
mxs_chan->status = DMA_PAUSED;
|
||||
}
|
||||
@ -184,21 +263,16 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
|
||||
int chan_id = mxs_chan->chan.chan_id;
|
||||
|
||||
/* unfreeze the channel */
|
||||
if (dma_is_apbh() && apbh_is_old())
|
||||
if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
|
||||
writel(1 << chan_id,
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR);
|
||||
else
|
||||
writel(1 << chan_id,
|
||||
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_CLR_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_CLR);
|
||||
|
||||
mxs_chan->status = DMA_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
|
||||
{
|
||||
return container_of(chan, struct mxs_dma_chan, chan);
|
||||
}
|
||||
|
||||
static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
|
||||
{
|
||||
return dma_cookie_assign(tx);
|
||||
@ -220,11 +294,11 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
|
||||
/* completion status */
|
||||
stat1 = readl(mxs_dma->base + HW_APBHX_CTRL1);
|
||||
stat1 &= MXS_DMA_CHANNELS_MASK;
|
||||
writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + MXS_CLR_ADDR);
|
||||
writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR);
|
||||
|
||||
/* error status */
|
||||
stat2 = readl(mxs_dma->base + HW_APBHX_CTRL2);
|
||||
writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + MXS_CLR_ADDR);
|
||||
writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + STMP_OFFSET_REG_CLR);
|
||||
|
||||
/*
|
||||
* When both completion and error of termination bits set at the
|
||||
@ -567,27 +641,21 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mxs_reset_block(mxs_dma->base);
|
||||
ret = stmp_reset_block(mxs_dma->base);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
|
||||
/* only major version matters */
|
||||
mxs_dma->version = readl(mxs_dma->base +
|
||||
((mxs_dma->dev_id == MXS_DMA_APBX) ?
|
||||
HW_APBX_VERSION : HW_APBH_VERSION)) >>
|
||||
BP_APBHX_VERSION_MAJOR;
|
||||
|
||||
/* enable apbh burst */
|
||||
if (dma_is_apbh()) {
|
||||
if (dma_is_apbh(mxs_dma)) {
|
||||
writel(BM_APBH_CTRL0_APB_BURST_EN,
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
|
||||
writel(BM_APBH_CTRL0_APB_BURST8_EN,
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
|
||||
}
|
||||
|
||||
/* enable irq for all the channels */
|
||||
writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS,
|
||||
mxs_dma->base + HW_APBHX_CTRL1 + MXS_SET_ADDR);
|
||||
mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET);
|
||||
|
||||
err_out:
|
||||
clk_disable_unprepare(mxs_dma->clk);
|
||||
@ -596,8 +664,9 @@ err_out:
|
||||
|
||||
static int __init mxs_dma_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct platform_device_id *id_entry =
|
||||
platform_get_device_id(pdev);
|
||||
const struct platform_device_id *id_entry;
|
||||
const struct of_device_id *of_id;
|
||||
const struct mxs_dma_type *dma_type;
|
||||
struct mxs_dma_engine *mxs_dma;
|
||||
struct resource *iores;
|
||||
int ret, i;
|
||||
@ -606,7 +675,15 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
|
||||
if (!mxs_dma)
|
||||
return -ENOMEM;
|
||||
|
||||
mxs_dma->dev_id = id_entry->driver_data;
|
||||
of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev);
|
||||
if (of_id)
|
||||
id_entry = of_id->data;
|
||||
else
|
||||
id_entry = platform_get_device_id(pdev);
|
||||
|
||||
dma_type = (struct mxs_dma_type *)id_entry->driver_data;
|
||||
mxs_dma->type = dma_type->type;
|
||||
mxs_dma->dev_id = dma_type->id;
|
||||
|
||||
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
@ -689,23 +766,12 @@ err_request_region:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_device_id mxs_dma_type[] = {
|
||||
{
|
||||
.name = "mxs-dma-apbh",
|
||||
.driver_data = MXS_DMA_APBH,
|
||||
}, {
|
||||
.name = "mxs-dma-apbx",
|
||||
.driver_data = MXS_DMA_APBX,
|
||||
}, {
|
||||
/* end of list */
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver mxs_dma_driver = {
|
||||
.driver = {
|
||||
.name = "mxs-dma",
|
||||
.of_match_table = mxs_dma_dt_ids,
|
||||
},
|
||||
.id_table = mxs_dma_type,
|
||||
.id_table = mxs_dma_ids,
|
||||
};
|
||||
|
||||
static int __init mxs_dma_module_init(void)
|
||||
|
@ -25,23 +25,25 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/basic_mmio_gpio.h>
|
||||
#include <linux/module.h>
|
||||
#include <mach/mxs.h>
|
||||
|
||||
#define MXS_SET 0x4
|
||||
#define MXS_CLR 0x8
|
||||
|
||||
#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
|
||||
#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
|
||||
#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
|
||||
#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
|
||||
#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
|
||||
#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
|
||||
#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
|
||||
#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
|
||||
#define PINCTRL_DOUT(p) ((is_imx23_gpio(p) ? 0x0500 : 0x0700) + (p->id) * 0x10)
|
||||
#define PINCTRL_DIN(p) ((is_imx23_gpio(p) ? 0x0600 : 0x0900) + (p->id) * 0x10)
|
||||
#define PINCTRL_DOE(p) ((is_imx23_gpio(p) ? 0x0700 : 0x0b00) + (p->id) * 0x10)
|
||||
#define PINCTRL_PIN2IRQ(p) ((is_imx23_gpio(p) ? 0x0800 : 0x1000) + (p->id) * 0x10)
|
||||
#define PINCTRL_IRQEN(p) ((is_imx23_gpio(p) ? 0x0900 : 0x1100) + (p->id) * 0x10)
|
||||
#define PINCTRL_IRQLEV(p) ((is_imx23_gpio(p) ? 0x0a00 : 0x1200) + (p->id) * 0x10)
|
||||
#define PINCTRL_IRQPOL(p) ((is_imx23_gpio(p) ? 0x0b00 : 0x1300) + (p->id) * 0x10)
|
||||
#define PINCTRL_IRQSTAT(p) ((is_imx23_gpio(p) ? 0x0c00 : 0x1400) + (p->id) * 0x10)
|
||||
|
||||
#define GPIO_INT_FALL_EDGE 0x0
|
||||
#define GPIO_INT_LOW_LEV 0x1
|
||||
@ -52,14 +54,30 @@
|
||||
|
||||
#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
|
||||
|
||||
enum mxs_gpio_id {
|
||||
IMX23_GPIO,
|
||||
IMX28_GPIO,
|
||||
};
|
||||
|
||||
struct mxs_gpio_port {
|
||||
void __iomem *base;
|
||||
int id;
|
||||
int irq;
|
||||
int virtual_irq_start;
|
||||
struct bgpio_chip bgc;
|
||||
enum mxs_gpio_id devid;
|
||||
};
|
||||
|
||||
static inline int is_imx23_gpio(struct mxs_gpio_port *port)
|
||||
{
|
||||
return port->devid == IMX23_GPIO;
|
||||
}
|
||||
|
||||
static inline int is_imx28_gpio(struct mxs_gpio_port *port)
|
||||
{
|
||||
return port->devid == IMX28_GPIO;
|
||||
}
|
||||
|
||||
/* Note: This driver assumes 32 GPIOs are handled in one register */
|
||||
|
||||
static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
|
||||
@ -89,21 +107,21 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
|
||||
}
|
||||
|
||||
/* set level or edge */
|
||||
pin_addr = port->base + PINCTRL_IRQLEV(port->id);
|
||||
pin_addr = port->base + PINCTRL_IRQLEV(port);
|
||||
if (edge & GPIO_INT_LEV_MASK)
|
||||
writel(pin_mask, pin_addr + MXS_SET);
|
||||
else
|
||||
writel(pin_mask, pin_addr + MXS_CLR);
|
||||
|
||||
/* set polarity */
|
||||
pin_addr = port->base + PINCTRL_IRQPOL(port->id);
|
||||
pin_addr = port->base + PINCTRL_IRQPOL(port);
|
||||
if (edge & GPIO_INT_POL_MASK)
|
||||
writel(pin_mask, pin_addr + MXS_SET);
|
||||
else
|
||||
writel(pin_mask, pin_addr + MXS_CLR);
|
||||
|
||||
writel(1 << (gpio & 0x1f),
|
||||
port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
|
||||
port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -117,8 +135,8 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
|
||||
|
||||
desc->irq_data.chip->irq_ack(&desc->irq_data);
|
||||
|
||||
irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) &
|
||||
readl(port->base + PINCTRL_IRQEN(port->id));
|
||||
irq_stat = readl(port->base + PINCTRL_IRQSTAT(port)) &
|
||||
readl(port->base + PINCTRL_IRQEN(port));
|
||||
|
||||
while (irq_stat != 0) {
|
||||
int irqoffset = fls(irq_stat) - 1;
|
||||
@ -164,8 +182,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
|
||||
ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_set_type = mxs_gpio_set_irq_type;
|
||||
ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
|
||||
ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR;
|
||||
ct->regs.mask = PINCTRL_IRQEN(port->id);
|
||||
ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
|
||||
ct->regs.mask = PINCTRL_IRQEN(port);
|
||||
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
|
||||
}
|
||||
@ -179,60 +197,83 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
return port->virtual_irq_start + offset;
|
||||
}
|
||||
|
||||
static struct platform_device_id mxs_gpio_ids[] = {
|
||||
{
|
||||
.name = "imx23-gpio",
|
||||
.driver_data = IMX23_GPIO,
|
||||
}, {
|
||||
.name = "imx28-gpio",
|
||||
.driver_data = IMX28_GPIO,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, mxs_gpio_ids);
|
||||
|
||||
static const struct of_device_id mxs_gpio_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx23-gpio", .data = (void *) IMX23_GPIO, },
|
||||
{ .compatible = "fsl,imx28-gpio", .data = (void *) IMX28_GPIO, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids);
|
||||
|
||||
static int __devinit mxs_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(mxs_gpio_dt_ids, &pdev->dev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *parent;
|
||||
static void __iomem *base;
|
||||
struct mxs_gpio_port *port;
|
||||
struct resource *iores = NULL;
|
||||
int err;
|
||||
|
||||
port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL);
|
||||
port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return -ENOMEM;
|
||||
|
||||
port->id = pdev->id;
|
||||
if (np) {
|
||||
port->id = of_alias_get_id(np, "gpio");
|
||||
if (port->id < 0)
|
||||
return port->id;
|
||||
port->devid = (enum mxs_gpio_id) of_id->data;
|
||||
} else {
|
||||
port->id = pdev->id;
|
||||
port->devid = pdev->id_entry->driver_data;
|
||||
}
|
||||
port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
|
||||
|
||||
port->irq = platform_get_irq(pdev, 0);
|
||||
if (port->irq < 0)
|
||||
return port->irq;
|
||||
|
||||
/*
|
||||
* map memory region only once, as all the gpio ports
|
||||
* share the same one
|
||||
*/
|
||||
if (!base) {
|
||||
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!iores) {
|
||||
err = -ENODEV;
|
||||
goto out_kfree;
|
||||
}
|
||||
|
||||
if (!request_mem_region(iores->start, resource_size(iores),
|
||||
pdev->name)) {
|
||||
err = -EBUSY;
|
||||
goto out_kfree;
|
||||
}
|
||||
|
||||
base = ioremap(iores->start, resource_size(iores));
|
||||
if (!base) {
|
||||
err = -ENOMEM;
|
||||
goto out_release_mem;
|
||||
if (np) {
|
||||
parent = of_get_parent(np);
|
||||
base = of_iomap(parent, 0);
|
||||
of_node_put(parent);
|
||||
} else {
|
||||
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_request_and_ioremap(&pdev->dev, iores);
|
||||
}
|
||||
if (!base)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
port->base = base;
|
||||
|
||||
port->irq = platform_get_irq(pdev, 0);
|
||||
if (port->irq < 0) {
|
||||
err = -EINVAL;
|
||||
goto out_iounmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* select the pin interrupt functionality but initially
|
||||
* disable the interrupts
|
||||
*/
|
||||
writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id));
|
||||
writel(0, port->base + PINCTRL_IRQEN(port->id));
|
||||
writel(~0U, port->base + PINCTRL_PIN2IRQ(port));
|
||||
writel(0, port->base + PINCTRL_IRQEN(port));
|
||||
|
||||
/* clear address has to be used to clear IRQSTAT bits */
|
||||
writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
|
||||
writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
|
||||
|
||||
/* gpio-mxs can be a generic irq chip */
|
||||
mxs_gpio_init_gc(port);
|
||||
@ -242,41 +283,32 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
|
||||
irq_set_handler_data(port->irq, port);
|
||||
|
||||
err = bgpio_init(&port->bgc, &pdev->dev, 4,
|
||||
port->base + PINCTRL_DIN(port->id),
|
||||
port->base + PINCTRL_DOUT(port->id), NULL,
|
||||
port->base + PINCTRL_DOE(port->id), NULL, false);
|
||||
port->base + PINCTRL_DIN(port),
|
||||
port->base + PINCTRL_DOUT(port), NULL,
|
||||
port->base + PINCTRL_DOE(port), NULL, false);
|
||||
if (err)
|
||||
goto out_iounmap;
|
||||
return err;
|
||||
|
||||
port->bgc.gc.to_irq = mxs_gpio_to_irq;
|
||||
port->bgc.gc.base = port->id * 32;
|
||||
|
||||
err = gpiochip_add(&port->bgc.gc);
|
||||
if (err)
|
||||
goto out_bgpio_remove;
|
||||
if (err) {
|
||||
bgpio_remove(&port->bgc);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_bgpio_remove:
|
||||
bgpio_remove(&port->bgc);
|
||||
out_iounmap:
|
||||
if (iores)
|
||||
iounmap(port->base);
|
||||
out_release_mem:
|
||||
if (iores)
|
||||
release_mem_region(iores->start, resource_size(iores));
|
||||
out_kfree:
|
||||
kfree(port);
|
||||
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct platform_driver mxs_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "gpio-mxs",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mxs_gpio_dt_ids,
|
||||
},
|
||||
.probe = mxs_gpio_probe,
|
||||
.id_table = mxs_gpio_ids,
|
||||
};
|
||||
|
||||
static int __init mxs_gpio_init(void)
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_i2c.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/hardware.h>
|
||||
@ -470,6 +471,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
|
||||
struct imx_i2c_struct *i2c_imx;
|
||||
struct resource *res;
|
||||
struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct pinctrl *pinctrl;
|
||||
void __iomem *base;
|
||||
resource_size_t res_size;
|
||||
int irq, bitrate;
|
||||
@ -520,6 +522,12 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
|
||||
i2c_imx->base = base;
|
||||
i2c_imx->res = res;
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* Get I2C clock */
|
||||
i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
|
||||
if (IS_ERR(i2c_imx->clk)) {
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_i2c.h>
|
||||
|
||||
#include <mach/common.h>
|
||||
|
||||
@ -325,10 +329,15 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mxs_i2c_dev *i2c;
|
||||
struct i2c_adapter *adap;
|
||||
struct pinctrl *pinctrl;
|
||||
struct resource *res;
|
||||
resource_size_t res_size;
|
||||
int err, irq;
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(dev);
|
||||
if (IS_ERR(pinctrl))
|
||||
return PTR_ERR(pinctrl);
|
||||
|
||||
i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
|
||||
if (!i2c)
|
||||
return -ENOMEM;
|
||||
@ -365,6 +374,7 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
|
||||
adap->algo = &mxs_i2c_algo;
|
||||
adap->dev.parent = dev;
|
||||
adap->nr = pdev->id;
|
||||
adap->dev.of_node = pdev->dev.of_node;
|
||||
i2c_set_adapdata(adap, i2c);
|
||||
err = i2c_add_numbered_adapter(adap);
|
||||
if (err) {
|
||||
@ -374,6 +384,8 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
of_i2c_register_devices(adap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -393,10 +405,17 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mxs_i2c_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx28-i2c", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
|
||||
|
||||
static struct platform_driver mxs_i2c_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mxs_i2c_dt_ids,
|
||||
},
|
||||
.remove = __devexit_p(mxs_i2c_remove),
|
||||
};
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -39,18 +42,16 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fsl/mxs-dma.h>
|
||||
|
||||
#include <mach/mxs.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/mmc.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/stmp_device.h>
|
||||
#include <linux/mmc/mxs-mmc.h>
|
||||
|
||||
#define DRIVER_NAME "mxs-mmc"
|
||||
|
||||
/* card detect polling timeout */
|
||||
#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
|
||||
|
||||
#define SSP_VERSION_LATEST 4
|
||||
#define ssp_is_old() (host->version < SSP_VERSION_LATEST)
|
||||
#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
|
||||
|
||||
/* SSP registers */
|
||||
#define HW_SSP_CTRL0 0x000
|
||||
@ -85,14 +86,14 @@
|
||||
#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
|
||||
#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
|
||||
#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
|
||||
#define HW_SSP_TIMING (ssp_is_old() ? 0x050 : 0x070)
|
||||
#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
|
||||
#define BP_SSP_TIMING_TIMEOUT (16)
|
||||
#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
|
||||
#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
|
||||
#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
|
||||
#define BP_SSP_TIMING_CLOCK_RATE (0)
|
||||
#define BM_SSP_TIMING_CLOCK_RATE (0xff)
|
||||
#define HW_SSP_CTRL1 (ssp_is_old() ? 0x060 : 0x080)
|
||||
#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
|
||||
#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
|
||||
#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
|
||||
#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
|
||||
@ -115,15 +116,13 @@
|
||||
#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
|
||||
#define BP_SSP_CTRL1_SSP_MODE (0)
|
||||
#define BM_SSP_CTRL1_SSP_MODE (0xf)
|
||||
#define HW_SSP_SDRESP0 (ssp_is_old() ? 0x080 : 0x0a0)
|
||||
#define HW_SSP_SDRESP1 (ssp_is_old() ? 0x090 : 0x0b0)
|
||||
#define HW_SSP_SDRESP2 (ssp_is_old() ? 0x0a0 : 0x0c0)
|
||||
#define HW_SSP_SDRESP3 (ssp_is_old() ? 0x0b0 : 0x0d0)
|
||||
#define HW_SSP_STATUS (ssp_is_old() ? 0x0c0 : 0x100)
|
||||
#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
|
||||
#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
|
||||
#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
|
||||
#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
|
||||
#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
|
||||
#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
|
||||
#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
|
||||
#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130)
|
||||
#define BP_SSP_VERSION_MAJOR (24)
|
||||
|
||||
#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
|
||||
|
||||
@ -138,6 +137,11 @@
|
||||
|
||||
#define SSP_PIO_NUM 3
|
||||
|
||||
enum mxs_mmc_id {
|
||||
IMX23_MMC,
|
||||
IMX28_MMC,
|
||||
};
|
||||
|
||||
struct mxs_mmc_host {
|
||||
struct mmc_host *mmc;
|
||||
struct mmc_request *mrq;
|
||||
@ -145,9 +149,7 @@ struct mxs_mmc_host {
|
||||
struct mmc_data *data;
|
||||
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
struct resource *res;
|
||||
struct resource *dma_res;
|
||||
int dma_channel;
|
||||
struct clk *clk;
|
||||
unsigned int clk_rate;
|
||||
|
||||
@ -157,32 +159,28 @@ struct mxs_mmc_host {
|
||||
enum dma_transfer_direction slave_dirn;
|
||||
u32 ssp_pio_words[SSP_PIO_NUM];
|
||||
|
||||
unsigned int version;
|
||||
enum mxs_mmc_id devid;
|
||||
unsigned char bus_width;
|
||||
spinlock_t lock;
|
||||
int sdio_irq_en;
|
||||
int wp_gpio;
|
||||
};
|
||||
|
||||
static int mxs_mmc_get_ro(struct mmc_host *mmc)
|
||||
{
|
||||
struct mxs_mmc_host *host = mmc_priv(mmc);
|
||||
struct mxs_mmc_platform_data *pdata =
|
||||
mmc_dev(host->mmc)->platform_data;
|
||||
|
||||
if (!pdata)
|
||||
return -EFAULT;
|
||||
|
||||
if (!gpio_is_valid(pdata->wp_gpio))
|
||||
if (!gpio_is_valid(host->wp_gpio))
|
||||
return -EINVAL;
|
||||
|
||||
return gpio_get_value(pdata->wp_gpio);
|
||||
return gpio_get_value(host->wp_gpio);
|
||||
}
|
||||
|
||||
static int mxs_mmc_get_cd(struct mmc_host *mmc)
|
||||
{
|
||||
struct mxs_mmc_host *host = mmc_priv(mmc);
|
||||
|
||||
return !(readl(host->base + HW_SSP_STATUS) &
|
||||
return !(readl(host->base + HW_SSP_STATUS(host)) &
|
||||
BM_SSP_STATUS_CARD_DETECT);
|
||||
}
|
||||
|
||||
@ -190,7 +188,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
|
||||
{
|
||||
u32 ctrl0, ctrl1;
|
||||
|
||||
mxs_reset_block(host->base);
|
||||
stmp_reset_block(host->base);
|
||||
|
||||
ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
|
||||
ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
|
||||
@ -206,7 +204,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
|
||||
writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
|
||||
BF_SSP(2, TIMING_CLOCK_DIVIDE) |
|
||||
BF_SSP(0, TIMING_CLOCK_RATE),
|
||||
host->base + HW_SSP_TIMING);
|
||||
host->base + HW_SSP_TIMING(host));
|
||||
|
||||
if (host->sdio_irq_en) {
|
||||
ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
|
||||
@ -214,7 +212,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
|
||||
}
|
||||
|
||||
writel(ctrl0, host->base + HW_SSP_CTRL0);
|
||||
writel(ctrl1, host->base + HW_SSP_CTRL1);
|
||||
writel(ctrl1, host->base + HW_SSP_CTRL1(host));
|
||||
}
|
||||
|
||||
static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
|
||||
@ -228,12 +226,12 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
|
||||
|
||||
if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
|
||||
if (mmc_resp_type(cmd) & MMC_RSP_136) {
|
||||
cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
|
||||
cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
|
||||
cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
|
||||
cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
|
||||
cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
|
||||
cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
|
||||
cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
|
||||
cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
|
||||
} else {
|
||||
cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
|
||||
cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,9 +274,9 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
|
||||
|
||||
spin_lock(&host->lock);
|
||||
|
||||
stat = readl(host->base + HW_SSP_CTRL1);
|
||||
stat = readl(host->base + HW_SSP_CTRL1(host));
|
||||
writel(stat & MXS_MMC_IRQ_BITS,
|
||||
host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
|
||||
host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
|
||||
|
||||
if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
|
||||
mmc_signal_sdio_irq(host->mmc);
|
||||
@ -484,7 +482,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
|
||||
blocks = 1;
|
||||
|
||||
/* xfer count, block size and count need to be set differently */
|
||||
if (ssp_is_old()) {
|
||||
if (ssp_is_old(host)) {
|
||||
ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
|
||||
cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
|
||||
BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
|
||||
@ -508,10 +506,10 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
|
||||
|
||||
/* set the timeout count */
|
||||
timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
|
||||
val = readl(host->base + HW_SSP_TIMING);
|
||||
val = readl(host->base + HW_SSP_TIMING(host));
|
||||
val &= ~(BM_SSP_TIMING_TIMEOUT);
|
||||
val |= BF_SSP(timeout, TIMING_TIMEOUT);
|
||||
writel(val, host->base + HW_SSP_TIMING);
|
||||
writel(val, host->base + HW_SSP_TIMING(host));
|
||||
|
||||
/* pio */
|
||||
host->ssp_pio_words[0] = ctrl0;
|
||||
@ -597,11 +595,11 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
|
||||
|
||||
ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
|
||||
|
||||
val = readl(host->base + HW_SSP_TIMING);
|
||||
val = readl(host->base + HW_SSP_TIMING(host));
|
||||
val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
|
||||
val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
|
||||
val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
|
||||
writel(val, host->base + HW_SSP_TIMING);
|
||||
writel(val, host->base + HW_SSP_TIMING(host));
|
||||
|
||||
host->clk_rate = ssp_sck;
|
||||
|
||||
@ -636,18 +634,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
|
||||
|
||||
if (enable) {
|
||||
writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
|
||||
host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
|
||||
host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
|
||||
writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
|
||||
host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
|
||||
host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
|
||||
|
||||
if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
|
||||
if (readl(host->base + HW_SSP_STATUS(host)) &
|
||||
BM_SSP_STATUS_SDIO_IRQ)
|
||||
mmc_signal_sdio_irq(host->mmc);
|
||||
|
||||
} else {
|
||||
writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
|
||||
host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
|
||||
host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
|
||||
writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
|
||||
host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
|
||||
host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
@ -668,7 +667,7 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
|
||||
if (!mxs_dma_is_apbh(chan))
|
||||
return false;
|
||||
|
||||
if (chan->chan_id != host->dma_res->start)
|
||||
if (chan->chan_id != host->dma_channel)
|
||||
return false;
|
||||
|
||||
chan->private = &host->dma_data;
|
||||
@ -676,12 +675,36 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct platform_device_id mxs_mmc_ids[] = {
|
||||
{
|
||||
.name = "imx23-mmc",
|
||||
.driver_data = IMX23_MMC,
|
||||
}, {
|
||||
.name = "imx28-mmc",
|
||||
.driver_data = IMX28_MMC,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, mxs_mmc_ids);
|
||||
|
||||
static const struct of_device_id mxs_mmc_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, },
|
||||
{ .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
|
||||
|
||||
static int mxs_mmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(mxs_mmc_dt_ids, &pdev->dev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct mxs_mmc_host *host;
|
||||
struct mmc_host *mmc;
|
||||
struct resource *iores, *dmares, *r;
|
||||
struct resource *iores, *dmares;
|
||||
struct mxs_mmc_platform_data *pdata;
|
||||
struct pinctrl *pinctrl;
|
||||
int ret = 0, irq_err, irq_dma;
|
||||
dma_cap_mask_t mask;
|
||||
|
||||
@ -689,40 +712,51 @@ static int mxs_mmc_probe(struct platform_device *pdev)
|
||||
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
irq_err = platform_get_irq(pdev, 0);
|
||||
irq_dma = platform_get_irq(pdev, 1);
|
||||
if (!iores || !dmares || irq_err < 0 || irq_dma < 0)
|
||||
if (!iores || irq_err < 0 || irq_dma < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = request_mem_region(iores->start, resource_size(iores), pdev->name);
|
||||
if (!r)
|
||||
return -EBUSY;
|
||||
|
||||
mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
|
||||
if (!mmc) {
|
||||
ret = -ENOMEM;
|
||||
goto out_release_mem;
|
||||
}
|
||||
if (!mmc)
|
||||
return -ENOMEM;
|
||||
|
||||
host = mmc_priv(mmc);
|
||||
host->base = ioremap(r->start, resource_size(r));
|
||||
host->base = devm_request_and_ioremap(&pdev->dev, iores);
|
||||
if (!host->base) {
|
||||
ret = -ENOMEM;
|
||||
ret = -EADDRNOTAVAIL;
|
||||
goto out_mmc_free;
|
||||
}
|
||||
|
||||
/* only major verion does matter */
|
||||
host->version = readl(host->base + HW_SSP_VERSION) >>
|
||||
BP_SSP_VERSION_MAJOR;
|
||||
if (np) {
|
||||
host->devid = (enum mxs_mmc_id) of_id->data;
|
||||
/*
|
||||
* TODO: This is a temporary solution and should be changed
|
||||
* to use generic DMA binding later when the helpers get in.
|
||||
*/
|
||||
ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
|
||||
&host->dma_channel);
|
||||
if (ret) {
|
||||
dev_err(mmc_dev(host->mmc),
|
||||
"failed to get dma channel\n");
|
||||
goto out_mmc_free;
|
||||
}
|
||||
} else {
|
||||
host->devid = pdev->id_entry->driver_data;
|
||||
host->dma_channel = dmares->start;
|
||||
}
|
||||
|
||||
host->mmc = mmc;
|
||||
host->res = r;
|
||||
host->dma_res = dmares;
|
||||
host->irq = irq_err;
|
||||
host->sdio_irq_en = 0;
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto out_mmc_free;
|
||||
}
|
||||
|
||||
host->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(host->clk)) {
|
||||
ret = PTR_ERR(host->clk);
|
||||
goto out_iounmap;
|
||||
goto out_mmc_free;
|
||||
}
|
||||
clk_prepare_enable(host->clk);
|
||||
|
||||
@ -744,11 +778,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
|
||||
MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
|
||||
|
||||
pdata = mmc_dev(host->mmc)->platform_data;
|
||||
if (pdata) {
|
||||
if (!pdata) {
|
||||
u32 bus_width = 0;
|
||||
of_property_read_u32(np, "bus-width", &bus_width);
|
||||
if (bus_width == 4)
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
else if (bus_width == 8)
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
|
||||
host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
|
||||
} else {
|
||||
if (pdata->flags & SLOTF_8_BIT_CAPABLE)
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
|
||||
if (pdata->flags & SLOTF_4_BIT_CAPABLE)
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
host->wp_gpio = pdata->wp_gpio;
|
||||
}
|
||||
|
||||
mmc->f_min = 400000;
|
||||
@ -757,13 +800,14 @@ static int mxs_mmc_probe(struct platform_device *pdev)
|
||||
|
||||
mmc->max_segs = 52;
|
||||
mmc->max_blk_size = 1 << 0xf;
|
||||
mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff;
|
||||
mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff;
|
||||
mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
|
||||
mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
|
||||
mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
|
||||
|
||||
platform_set_drvdata(pdev, mmc);
|
||||
|
||||
ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host);
|
||||
ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
|
||||
DRIVER_NAME, host);
|
||||
if (ret)
|
||||
goto out_free_dma;
|
||||
|
||||
@ -771,26 +815,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
goto out_free_irq;
|
||||
goto out_free_dma;
|
||||
|
||||
dev_info(mmc_dev(host->mmc), "initialized\n");
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_irq:
|
||||
free_irq(host->irq, host);
|
||||
out_free_dma:
|
||||
if (host->dmach)
|
||||
dma_release_channel(host->dmach);
|
||||
out_clk_put:
|
||||
clk_disable_unprepare(host->clk);
|
||||
clk_put(host->clk);
|
||||
out_iounmap:
|
||||
iounmap(host->base);
|
||||
out_mmc_free:
|
||||
mmc_free_host(mmc);
|
||||
out_release_mem:
|
||||
release_mem_region(iores->start, resource_size(iores));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -798,12 +836,9 @@ static int mxs_mmc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mmc_host *mmc = platform_get_drvdata(pdev);
|
||||
struct mxs_mmc_host *host = mmc_priv(mmc);
|
||||
struct resource *res = host->res;
|
||||
|
||||
mmc_remove_host(mmc);
|
||||
|
||||
free_irq(host->irq, host);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
if (host->dmach)
|
||||
@ -812,12 +847,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(host->clk);
|
||||
clk_put(host->clk);
|
||||
|
||||
iounmap(host->base);
|
||||
|
||||
mmc_free_host(mmc);
|
||||
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -857,11 +888,13 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
|
||||
static struct platform_driver mxs_mmc_driver = {
|
||||
.probe = mxs_mmc_probe,
|
||||
.remove = mxs_mmc_remove,
|
||||
.id_table = mxs_mmc_ids,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &mxs_mmc_pm_ops,
|
||||
.of_match_table = mxs_mmc_dt_ids,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <mach/esdhc.h>
|
||||
#include "sdhci-pltfm.h"
|
||||
#include "sdhci-esdhc.h"
|
||||
@ -68,6 +69,7 @@ struct pltfm_imx_data {
|
||||
int flags;
|
||||
u32 scratchpad;
|
||||
enum imx_esdhc_type devtype;
|
||||
struct pinctrl *pinctrl;
|
||||
struct esdhc_platform_data boarddata;
|
||||
};
|
||||
|
||||
@ -467,6 +469,12 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
||||
clk_prepare_enable(clk);
|
||||
pltfm_host->clk = clk;
|
||||
|
||||
imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(imx_data->pinctrl)) {
|
||||
err = PTR_ERR(imx_data->pinctrl);
|
||||
goto pin_err;
|
||||
}
|
||||
|
||||
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
|
||||
|
||||
if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
|
||||
@ -558,6 +566,7 @@ no_card_detect_irq:
|
||||
gpio_free(boarddata->wp_gpio);
|
||||
no_card_detect_pin:
|
||||
no_board_data:
|
||||
pin_err:
|
||||
clk_disable_unprepare(pltfm_host->clk);
|
||||
clk_put(pltfm_host->clk);
|
||||
err_clk_get:
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/gpmi-nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include "gpmi-nand.h"
|
||||
|
||||
/* add our owner bbt descriptor */
|
||||
@ -476,6 +477,7 @@ acquire_err:
|
||||
static int __devinit acquire_resources(struct gpmi_nand_data *this)
|
||||
{
|
||||
struct resources *res = &this->resources;
|
||||
struct pinctrl *pinctrl;
|
||||
int ret;
|
||||
|
||||
ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME);
|
||||
@ -494,6 +496,12 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
|
||||
if (ret)
|
||||
goto exit_dma_channels;
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto exit_pin;
|
||||
}
|
||||
|
||||
res->clock = clk_get(&this->pdev->dev, NULL);
|
||||
if (IS_ERR(res->clock)) {
|
||||
pr_err("can not get the clock\n");
|
||||
@ -503,6 +511,7 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
|
||||
return 0;
|
||||
|
||||
exit_clock:
|
||||
exit_pin:
|
||||
release_dma_channels(this);
|
||||
exit_dma_channels:
|
||||
release_bch_irq(this);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#define DRV_NAME "flexcan"
|
||||
|
||||
@ -927,11 +928,16 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
|
||||
struct flexcan_priv *priv;
|
||||
struct resource *mem;
|
||||
struct clk *clk = NULL;
|
||||
struct pinctrl *pinctrl;
|
||||
void __iomem *base;
|
||||
resource_size_t mem_size;
|
||||
int err, irq;
|
||||
u32 clock_freq = 0;
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl))
|
||||
return PTR_ERR(pinctrl);
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
const u32 *clock_freq_p;
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
@ -1542,6 +1543,7 @@ fec_probe(struct platform_device *pdev)
|
||||
struct resource *r;
|
||||
const struct of_device_id *of_id;
|
||||
static int dev_id;
|
||||
struct pinctrl *pinctrl;
|
||||
|
||||
of_id = of_match_device(fec_dt_ids, &pdev->dev);
|
||||
if (of_id)
|
||||
@ -1609,6 +1611,12 @@ fec_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto failed_pin;
|
||||
}
|
||||
|
||||
fep->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(fep->clk)) {
|
||||
ret = PTR_ERR(fep->clk);
|
||||
@ -1639,6 +1647,7 @@ failed_mii_init:
|
||||
failed_init:
|
||||
clk_disable_unprepare(fep->clk);
|
||||
clk_put(fep->clk);
|
||||
failed_pin:
|
||||
failed_clk:
|
||||
for (i = 0; i < FEC_IRQ_NUM; i++) {
|
||||
irq = platform_get_irq(pdev, i);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <mach/spi.h>
|
||||
|
||||
@ -758,6 +759,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
|
||||
struct spi_master *master;
|
||||
struct spi_imx_data *spi_imx;
|
||||
struct resource *res;
|
||||
struct pinctrl *pinctrl;
|
||||
int i, ret, num_cs;
|
||||
|
||||
if (!np && !mxc_platform_info) {
|
||||
@ -845,6 +847,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
|
||||
goto out_iounmap;
|
||||
}
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto out_free_irq;
|
||||
}
|
||||
|
||||
spi_imx->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(spi_imx->clk)) {
|
||||
dev_err(&pdev->dev, "unable to get clock\n");
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/sizes.h>
|
||||
@ -1916,6 +1917,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
{
|
||||
struct uart_amba_port *uap;
|
||||
struct vendor_data *vendor = id->data;
|
||||
struct pinctrl *pinctrl;
|
||||
void __iomem *base;
|
||||
int i, ret;
|
||||
|
||||
@ -1940,6 +1942,12 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
goto free;
|
||||
}
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&dev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
uap->clk = clk_get(&dev->dev, NULL);
|
||||
if (IS_ERR(uap->clk)) {
|
||||
ret = PTR_ERR(uap->clk);
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@ -1464,6 +1465,7 @@ static int serial_imx_probe(struct platform_device *pdev)
|
||||
void __iomem *base;
|
||||
int ret = 0;
|
||||
struct resource *res;
|
||||
struct pinctrl *pinctrl;
|
||||
|
||||
sport = kzalloc(sizeof(*sport), GFP_KERNEL);
|
||||
if (!sport)
|
||||
@ -1503,6 +1505,12 @@ static int serial_imx_probe(struct platform_device *pdev)
|
||||
sport->timer.function = imx_timeout;
|
||||
sport->timer.data = (unsigned long)sport;
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
sport->clk = clk_get(&pdev->dev, "uart");
|
||||
if (IS_ERR(sport->clk)) {
|
||||
ret = PTR_ERR(sport->clk);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
@ -678,6 +679,7 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
|
||||
u32 version;
|
||||
int ret = 0;
|
||||
struct resource *r;
|
||||
struct pinctrl *pinctrl;
|
||||
|
||||
s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
|
||||
if (!s) {
|
||||
@ -685,6 +687,12 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
s->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(s->clk)) {
|
||||
ret = PTR_ERR(s->clk);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <mach/mxsfb.h>
|
||||
|
||||
#define REG_SET 4
|
||||
@ -756,6 +757,7 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
|
||||
struct mxsfb_info *host;
|
||||
struct fb_info *fb_info;
|
||||
struct fb_modelist *modelist;
|
||||
struct pinctrl *pinctrl;
|
||||
int i, ret;
|
||||
|
||||
if (!pdata) {
|
||||
@ -793,6 +795,12 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
|
||||
|
||||
host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
goto error_getpin;
|
||||
}
|
||||
|
||||
host->clk = clk_get(&host->pdev->dev, NULL);
|
||||
if (IS_ERR(host->clk)) {
|
||||
ret = PTR_ERR(host->clk);
|
||||
@ -848,6 +856,7 @@ error_init_fb:
|
||||
error_pseudo_pallette:
|
||||
clk_put(host->clk);
|
||||
error_getclock:
|
||||
error_getpin:
|
||||
iounmap(host->base);
|
||||
error_ioremap:
|
||||
framebuffer_release(fb_info);
|
||||
|
@ -15,14 +15,6 @@ struct mxs_dma_data {
|
||||
int chan_irq;
|
||||
};
|
||||
|
||||
static inline int mxs_dma_is_apbh(struct dma_chan *chan)
|
||||
{
|
||||
return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbh");
|
||||
}
|
||||
|
||||
static inline int mxs_dma_is_apbx(struct dma_chan *chan)
|
||||
{
|
||||
return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbx");
|
||||
}
|
||||
|
||||
extern int mxs_dma_is_apbh(struct dma_chan *chan);
|
||||
extern int mxs_dma_is_apbx(struct dma_chan *chan);
|
||||
#endif /* __MACH_MXS_DMA_H__ */
|
||||
|
@ -6,8 +6,8 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MXS_MMC_H__
|
||||
#define __MACH_MXS_MMC_H__
|
||||
#ifndef __LINUX_MMC_MXS_MMC_H__
|
||||
#define __LINUX_MMC_MXS_MMC_H__
|
||||
|
||||
struct mxs_mmc_platform_data {
|
||||
int wp_gpio; /* write protect pin */
|
||||
@ -15,4 +15,5 @@ struct mxs_mmc_platform_data {
|
||||
#define SLOTF_4_BIT_CAPABLE (1 << 0)
|
||||
#define SLOTF_8_BIT_CAPABLE (1 << 1)
|
||||
};
|
||||
#endif /* __MACH_MXS_MMC_H__ */
|
||||
|
||||
#endif /* __LINUX_MMC_MXS_MMC_H__ */
|
@ -25,6 +25,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/fsl/mxs-dma.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
@ -625,6 +626,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
|
||||
struct resource *iores, *dmares;
|
||||
struct mxs_saif *saif;
|
||||
struct mxs_saif_platform_data *pdata;
|
||||
struct pinctrl *pinctrl;
|
||||
int ret = 0;
|
||||
|
||||
if (pdev->id >= ARRAY_SIZE(mxs_saif))
|
||||
@ -650,6 +652,12 @@ static int mxs_saif_probe(struct platform_device *pdev)
|
||||
saif->master_id = saif->id;
|
||||
}
|
||||
|
||||
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
|
||||
if (IS_ERR(pinctrl)) {
|
||||
ret = PTR_ERR(pinctrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
saif->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(saif->clk)) {
|
||||
ret = PTR_ERR(saif->clk);
|
||||
|
Loading…
x
Reference in New Issue
Block a user