Commit 03e86b3a authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'mxs-dt-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt2

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

The mxs device tree changes for 3.10:

* Move enet_out clk into device tree and have fec driver handle it.
* Convert mxsfb driver to generic display timings bindings, and remove
  the mxsfb auxdata from platform code.
* Add generic DMA device tree binding for mxs-dma, and convert the most
  of client device drivers to it.
* Change mxsfb driver to use regulator for controlling power of panel.
* A few device tree source updates

* tag 'mxs-dt-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6: (23 commits)
  video: mxsfb: Introduce regulator support
  ARM: dts: cfa10036: Add touchscreen support to the CFA-10049
  ARM: dts: imx23-olinuxino: mark sdcard cd as broken
  serial: mxs-auart: move to use generic DMA helper
  mtd: gpmi: move to use generic DMA helper
  i2c: i2c-mxs: move to use generic DMA helper
  spi: mxs-spi: move to use generic DMA helper
  mmc: mxs-mmc: move to use generic DMA helper
  dma: mxs-dma: move to generic device tree binding
  dma: mxs-dma: use devm_* managed functions
  ARM: dts: add generic DMA device tree binding for mxs-dma
  pinctrl: pinctrl-mxs: document the missing pull-ups
  ARM: cfa10036: add one wire bitbanging to the cfa10049
  video: mxsfb: remove mxsfb_platform_data
  ARM: mxs: move display timing configurations into device tree
  video: mxsfb: get display timings from device tree
  video: mxsfb: remove dotclk_delay from platform_data
  video: mxsfb: remove fb_phys/fb_size from platform_data
  video: mxsfb: use devm_* managed functions
  ARM: mxs: remove unneeded enet_out clk initialization
  ...
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 42d96abb 4344429d
......@@ -3,17 +3,58 @@
Required properties:
- compatible : Should be "fsl,<chip>-dma-apbh" or "fsl,<chip>-dma-apbx"
- reg : Should contain registers location and length
- interrupts : Should contain the interrupt numbers of DMA channels.
If a channel is empty/reserved, 0 should be filled in place.
- #dma-cells : Must be <1>. The number cell specifies the channel ID.
- dma-channels : Number of channels supported by the DMA controller
Optional properties:
- interrupt-names : Name of DMA channel interrupts
Supported chips:
imx23, imx28.
Examples:
dma-apbh@80004000 {
dma_apbh: dma-apbh@80004000 {
compatible = "fsl,imx28-dma-apbh";
reg = <0x80004000 2000>;
reg = <0x80004000 0x2000>;
interrupts = <82 83 84 85
88 88 88 88
88 88 88 88
87 86 0 0>;
interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
"gpmi0", "gmpi1", "gpmi2", "gmpi3",
"gpmi4", "gmpi5", "gpmi6", "gmpi7",
"hsadc", "lcdif", "empty", "empty";
#dma-cells = <1>;
dma-channels = <16>;
};
dma-apbx@80024000 {
dma_apbx: dma-apbx@80024000 {
compatible = "fsl,imx28-dma-apbx";
reg = <0x80024000 2000>;
reg = <0x80024000 0x2000>;
interrupts = <78 79 66 0
80 81 68 69
70 71 72 73
74 75 76 77>;
interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty",
"saif0", "saif1", "i2c0", "i2c1",
"auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
"auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
#dma-cells = <1>;
dma-channels = <16>;
};
DMA clients connected to the MXS DMA controller must use the format
described in the dma.txt file.
Examples:
auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112>;
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
};
......@@ -5,9 +5,16 @@ Required properties:
imx23 and imx28.
- reg: Address and length of the register set for lcdif
- interrupts: Should contain lcdif interrupts
- display : phandle to display node (see below for details)
Optional properties:
- panel-enable-gpios : Should specify the gpio for panel enable
* display node
Required properties:
- bits-per-pixel : <16> for RGB565, <32> for RGB888/666.
- bus-width : number of data lines. Could be <8>, <16>, <18> or <24>.
Required sub-node:
- display-timings : Refer to binding doc display-timing.txt for details.
Examples:
......@@ -15,5 +22,28 @@ lcdif@80030000 {
compatible = "fsl,imx28-lcdif";
reg = <0x80030000 2000>;
interrupts = <38 86>;
panel-enable-gpios = <&gpio3 30 0>;
display: display {
bits-per-pixel = <32>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <33500000>;
hactive = <800>;
vactive = <480>;
hfront-porch = <164>;
hback-porch = <89>;
hsync-len = <10>;
vback-porch = <23>;
vfront-porch = <10>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
......@@ -3,10 +3,13 @@
Required properties:
- compatible: Should be "fsl,<chip>-i2c"
- reg: Should contain registers location and length
- interrupts: Should contain ERROR and DMA interrupts
- interrupts: Should contain ERROR interrupt number
- clock-frequency: Desired I2C bus clock frequency in Hz.
Only 100000Hz and 400000Hz modes are supported.
- fsl,i2c-dma-channel: APBX DMA channel for the I2C
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and I2C DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: Must be "rx-tx".
Examples:
......@@ -15,7 +18,8 @@ i2c0: i2c@80058000 {
#size-cells = <0>;
compatible = "fsl,imx28-i2c";
reg = <0x80058000 2000>;
interrupts = <111 68>;
interrupts = <111>;
clock-frequency = <100000>;
fsl,i2c-dma-channel = <6>;
dmas = <&dma_apbx 6>;
dma-names = "rx-tx";
};
......@@ -9,15 +9,19 @@ and the properties used by the mxsmmc driver.
Required properties:
- compatible: Should be "fsl,<chip>-mmc". The supported chips include
imx23 and imx28.
- interrupts: Should contain ERROR and DMA interrupts
- fsl,ssp-dma-channel: APBH DMA channel for the SSP
- interrupts: Should contain ERROR interrupt number
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and SSP DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: Must be "rx-tx".
Examples:
ssp0: ssp@80010000 {
compatible = "fsl,imx28-mmc";
reg = <0x80010000 2000>;
interrupts = <96 82>;
fsl,ssp-dma-channel = <0>;
interrupts = <96>;
dmas = <&dma_apbh 0>;
dma-names = "rx-tx";
bus-width = <8>;
};
......@@ -7,10 +7,12 @@ Required properties:
- compatible : should be "fsl,<chip>-gpmi-nand"
- reg : should contain registers location and length for gpmi and bch.
- reg-names: Should contain the reg names "gpmi-nand" and "bch"
- interrupts : The first is the DMA interrupt number for GPMI.
The second is the BCH interrupt number.
- interrupt-names : The interrupt names "gpmi-dma", "bch";
- fsl,gpmi-dma-channel : Should contain the dma channel it uses.
- interrupts : BCH interrupt number.
- interrupt-names : Should be "bch".
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and GPMI DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: Must be "rx-tx".
Optional properties:
- nand-on-flash-bbt: boolean to enable on flash bbt option if not
......@@ -27,9 +29,10 @@ gpmi-nand@8000c000 {
#size-cells = <1>;
reg = <0x8000c000 2000>, <0x8000a000 2000>;
reg-names = "gpmi-nand", "bch";
interrupts = <88>, <41>;
interrupt-names = "gpmi-dma", "bch";
fsl,gpmi-dma-channel = <4>;
interrupts = <41>;
interrupt-names = "bch";
dmas = <&dma_apbh 4>;
dma-names = "rx-tx";
partition@0 {
...
......
......@@ -70,6 +70,10 @@ Optional subnode-properties:
0: Disable the internal pull-up
1: Enable the internal pull-up
Note that when enabling the pull-up, the internal pad keeper gets disabled.
Also, some pins doesn't have a pull up, in that case, setting the fsl,pull-up
will only disable the internal pad keeper.
Examples:
pinctrl@80018000 {
......
......@@ -3,8 +3,11 @@
Required properties:
- compatible: Should be "fsl,<soc>-spi", where soc is "imx23" or "imx28"
- reg: Offset and length of the register set for the device
- interrupts: Should contain SSP interrupts (error irq first, dma irq second)
- fsl,ssp-dma-channel: APBX DMA channel for the SSP
- interrupts: Should contain SSP ERROR interrupt
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and SSP DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: Must be "rx-tx".
Optional properties:
- clock-frequency : Input clock frequency to the SPI block in Hz.
......@@ -17,6 +20,7 @@ ssp0: ssp@80010000 {
#size-cells = <0>;
compatible = "fsl,imx28-spi";
reg = <0x80010000 0x2000>;
interrupts = <96 82>;
fsl,ssp-dma-channel = <0>;
interrupts = <96>;
dmas = <&dma_apbh 0>;
dma-names = "rx-tx";
};
......@@ -5,20 +5,18 @@ Required properties:
imx23 and imx28.
- reg : Address and length of the register set for the device
- interrupts : Should contain the auart interrupt numbers
Optional properties:
- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other
is for TX. If you add this property, it also means that you
will enable the DMA support for the auart.
Note: due to the hardware bug in imx23(see errata : 2836),
only the imx28 can enable the DMA support for the auart.
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and AUART DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: "rx" for RX channel, "tx" for TX channel.
Example:
auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
fsl,auart-dma-channel = <8 9>;
interrupts = <112>;
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
};
Note: Each auart port should have an alias correctly numbered in "aliases"
......
......@@ -59,8 +59,33 @@ hog_pins_a: hog@0 {
lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a>;
panel-enable-gpios = <&gpio1 18 0>;
lcd-supply = <&reg_lcd_3v3>;
display = <&display>;
status = "okay";
display: display {
bits-per-pixel = <32>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9200000>;
hactive = <480>;
vactive = <272>;
hback-porch = <15>;
hfront-porch = <8>;
vback-porch = <12>;
vfront-porch = <4>;
hsync-len = <1>;
vsync-len = <1>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
};
......@@ -95,6 +120,15 @@ reg_vddio_sd0: vddio-sd0 {
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 29 0>;
};
reg_lcd_3v3: lcd-3v3 {
compatible = "regulator-fixed";
regulator-name = "lcd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 18 0>;
enable-active-high;
};
};
backlight {
......
......@@ -29,6 +29,7 @@ ssp0: ssp@80010000 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
bus-width = <4>;
broken-cd;
status = "okay";
};
......
......@@ -49,9 +49,15 @@ icoll: interrupt-controller@80000000 {
reg = <0x80000000 0x2000>;
};
dma-apbh@80004000 {
dma_apbh: dma-apbh@80004000 {
compatible = "fsl,imx23-dma-apbh";
reg = <0x80004000 0x2000>;
interrupts = <0 14 20 0
13 13 13 13>;
interrupt-names = "empty", "ssp0", "ssp1", "empty",
"gpmi0", "gpmi1", "gpmi2", "gpmi3";
#dma-cells = <1>;
dma-channels = <8>;
clocks = <&clks 15>;
};
......@@ -70,6 +76,8 @@ gpmi-nand@8000c000 {
interrupt-names = "gpmi-dma", "bch";
clocks = <&clks 34>;
clock-names = "gpmi_io";
dmas = <&dma_apbh 4>;
dma-names = "rx-tx";
fsl,gpmi-dma-channel = <4>;
status = "disabled";
};
......@@ -78,6 +86,8 @@ ssp0: ssp@80010000 {
reg = <0x80010000 0x2000>;
interrupts = <15 14>;
clocks = <&clks 33>;
dmas = <&dma_apbh 1>;
dma-names = "rx-tx";
fsl,ssp-dma-channel = <1>;
status = "disabled";
};
......@@ -305,9 +315,19 @@ emi@80020000 {
status = "disabled";
};
dma-apbx@80024000 {
dma_apbx: dma-apbx@80024000 {
compatible = "fsl,imx23-dma-apbx";
reg = <0x80024000 0x2000>;
interrupts = <7 5 9 26
19 0 25 23
60 58 9 0
0 0 0 0>;
interrupt-names = "audio-adc", "audio-dac", "spdif-tx", "i2c",
"saif0", "empty", "auart0-rx", "auart0-tx",
"auart1-rx", "auart1-tx", "saif1", "empty",
"empty", "empty", "empty", "empty";
#dma-cells = <1>;
dma-channels = <16>;
clocks = <&clks 16>;
};
......@@ -344,6 +364,8 @@ ssp1: ssp@80034000 {
reg = <0x80034000 0x2000>;
interrupts = <2 20>;
clocks = <&clks 33>;
dmas = <&dma_apbh 2>;
dma-names = "rx-tx";
fsl,ssp-dma-channel = <2>;
status = "disabled";
};
......@@ -369,6 +391,8 @@ clks: clkctrl@80040000 {
saif0: saif@80042000 {
reg = <0x80042000 0x2000>;
dmas = <&dma_apbx 4>;
dma-names = "rx-tx";
status = "disabled";
};
......@@ -379,16 +403,22 @@ power@80044000 {
saif1: saif@80046000 {
reg = <0x80046000 0x2000>;
dmas = <&dma_apbx 10>;
dma-names = "rx-tx";
status = "disabled";
};
audio-out@80048000 {
reg = <0x80048000 0x2000>;
dmas = <&dma_apbx 1>;
dma-names = "tx";
status = "disabled";
};
audio-in@8004c000 {
reg = <0x8004c000 0x2000>;
dmas = <&dma_apbx 0>;
dma-names = "rx";
status = "disabled";
};
......@@ -401,11 +431,15 @@ lradc@80050000 {
spdif@80054000 {
reg = <0x80054000 2000>;
dmas = <&dma_apbx 2>;
dma-names = "tx";
status = "disabled";
};
i2c@80058000 {
reg = <0x80058000 0x2000>;
dmas = <&dma_apbx 3>;
dma-names = "rx-tx";
status = "disabled";
};
......@@ -436,6 +470,8 @@ auart0: serial@8006c000 {
reg = <0x8006c000 0x2000>;
interrupts = <24 25 23>;
clocks = <&clks 32>;
dmas = <&dma_apbx 6>, <&dma_apbx 7>;
dma-names = "rx", "tx";
status = "disabled";
};
......@@ -444,6 +480,8 @@ auart1: serial@8006e000 {
reg = <0x8006e000 0x2000>;
interrupts = <59 60 58>;
clocks = <&clks 32>;
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
status = "disabled";
};
......
......@@ -72,7 +72,32 @@ lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_16bit_pins_a
&lcdif_pins_apf28dev>;
display = <&display>;
status = "okay";
display: display {
bits-per-pixel = <16>;
bus-width = <16>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <33000033>;
hactive = <800>;
vactive = <480>;
hback-porch = <96>;
hfront-porch = <96>;
vback-porch = <20>;
vfront-porch = <21>;
hsync-len = <64>;
vsync-len = <4>;
hsync-active = <1>;
vsync-active = <1>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
};
......
......@@ -94,7 +94,32 @@ lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a
&lcdif_pins_apx4>;
display = <&display>;
status = "okay";
display: display {
bits-per-pixel = <32>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <30000000>;
hactive = <800>;
vactive = <480>;
hback-porch = <88>;
hfront-porch = <40>;
vback-porch = <32>;
vfront-porch = <13>;
hsync-len = <48>;
vsync-len = <3>;
hsync-active = <1>;
vsync-active = <1>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
};
......
......@@ -30,7 +30,6 @@ hog_pins_cfa10049: hog-10049@0 {
reg = <0>;
fsl,pinmux-ids = <
0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
0x1153 /* MX28_PAD_LCD_D22__GPIO_1_21 */
0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */
0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */
......@@ -120,13 +119,48 @@ lcdif_pins_cfa10049: lcdif-evk@0 {
fsl,voltage = <1>;
fsl,pull-up = <0>;
};
w1_gpio_pins: w1-gpio@0 {
reg = <0>;
fsl,pinmux-ids = <
0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */
>;
fsl,drive-strength = <1>;
fsl,voltage = <1>;
fsl,pull-up = <0>; /* 0 will enable the keeper */
};
};
lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_18bit_pins_cfa10049
&lcdif_pins_cfa10049>;
display = <&display>;
status = "okay";
display: display {
bits-per-pixel = <32>;
bus-width = <18>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9216000>;
hactive = <320>;
vactive = <480>;
hback-porch = <2>;
hfront-porch = <2>;
vback-porch = <2>;
vfront-porch = <2>;
hsync-len = <15>;
vsync-len = <15>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <1>;
};
};
};
};
};
......@@ -183,6 +217,11 @@ pca9555: pca9555@20 {
usbphy1: usbphy@8007e000 {
status = "okay";
};
lradc@80050000 {
status = "okay";
fsl,lradc-touchscreen-wires = <4>;
};
};
};
......@@ -304,5 +343,14 @@ backlight {
pwms = <&pwm 3 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
};
onewire@0 {
compatible = "w1-gpio";
pinctrl-names = "default";
pinctrl-0 = <&w1_gpio_pins>;
status = "okay";
gpios = <&gpio1 21 0>;
};
};
......@@ -123,8 +123,33 @@ lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a
&lcdif_pins_evk>;
panel-enable-gpios = <&gpio3 30 0>;
lcd-supply = <&reg_lcd_3v3>;
display = <&display>;
status = "okay";
display: display {
bits-per-pixel = <32>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <33500000>;
hactive = <800>;
vactive = <480>;
hback-porch = <89>;
hfront-porch = <164>;
vback-porch = <23>;
vfront-porch = <10>;
hsync-len = <10>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
can0: can@80032000 {
......@@ -285,6 +310,15 @@ reg_usb1_vbus: usb1_vbus {
gpio = <&gpio3 8 0>;
enable-active-high;
};
reg_lcd_3v3: lcd-3v3 {
compatible = "regulator-fixed";
regulator-name = "lcd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio3 30 0>;
enable-active-high;
};
};
sound {
......
......@@ -119,7 +119,32 @@ lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a
&lcdif_pins_m28>;
display = <&display>;
status = "okay";
display: display {
bits-per-pixel = <16>;
bus-width = <18>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <33260000>;
hactive = <800>;
vactive = <480>;
hback-porch = <0>;
hfront-porch = <256>;
vback-porch = <0>;
vfront-porch = <45>;
hsync-len = <1>;
vsync-len = <1>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <1>;
};
};
};
};
can0: can@80032000 {
......@@ -221,6 +246,8 @@ mac0: ethernet@800f0000 {
phy-mode = "rmii";
pinctrl-names = "default";
pinctrl-0 = <&mac0_pins_a>;
clocks = <&clks 57>, <&clks 57>;
clock-names = "ipg", "ahb";
status = "okay";
};
......
......@@ -61,12 +61,24 @@ icoll: interrupt-controller@80000000 {
hsadc@80002000 {
reg = <0x80002000 0x2000>;
interrupts = <13 87>;
dmas = <&dma_apbh 12>;
dma-names = "rx";
status = "disabled";
};
dma-apbh@80004000 {
dma_apbh: dma-apbh@80004000 {
compatible = "fsl,imx28-dma-apbh";
reg = <0x80004000 0x2000>;
interrupts = <82 83 84 85
88 88 88 88
88 88 88 88
87 86 0 0>;
interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
"gpmi0", "gmpi1", "gpmi2", "gmpi3",
"gpmi4", "gmpi5", "gpmi6", "gmpi7",
"hsadc", "lcdif", "empty", "empty";
#dma-cells = <1>;
dma-channels = <16>;
clocks = <&clks 25>;
};
......@@ -86,6 +98,8 @@ gpmi-nand@8000c000 {
interrupt-names = "gpmi-dma", "bch";
clocks = <&clks 50>;
clock-names = "gpmi_io";
dmas = <&dma_apbh 4>;
dma-names = "rx-tx";
fsl,gpmi-dma-channel = <4>;
status = "disabled";
};
......@@ -96,6 +110,8 @@ ssp0: ssp@80010000 {
reg = <0x80010000 0x2000>;
interrupts = <96 82>;
clocks = <&clks 46>;
dmas = <&dma_apbh 0>;
dma-names = "rx-tx";
fsl,ssp-dma-channel = <0>;
status = "disabled";
};
......@@ -106,6 +122,8 @@ ssp1: ssp@80012000 {
reg = <0x80012000 0x2000>;
interrupts = <97 83>;
clocks = <&clks 47>;
dmas = <&dma_apbh 1>;
dma-names = "rx-tx";
fsl,ssp-dma-channel = <1>;
status = "disabled";
};
......@@ -116,6 +134,8 @@ ssp2: ssp@80014000 {
reg = <0x80014000 0x2000>;
interrupts = <98 84>;
clocks = <&clks 48>;
dmas = <&dma_apbh 2>;
dma-names = "rx-tx";
fsl,ssp-dma-channel = <2>;
status = "disabled";
};
......@@ -126,6 +146,8 @@ ssp3: ssp@80016000 {
reg = <0x80016000 0x2000>;
interrupts = <99 85>;
clocks = <&clks 49>;
dmas = <&dma_apbh 3>;
dma-names = "rx-tx";
fsl,ssp-dma-channel = <3>;
status = "disabled";
};
......@@ -658,9 +680,19 @@ etm@80022000 {
status = "disabled";
};
dma-apbx@80024000 {
dma_apbx: dma-apbx@80024000 {
compatible = "fsl,imx28-dma-apbx";
reg = <0x80024000 0x2000>;
interrupts = <78 79 66 0
80 81 68 69
70 71 72 73
74 75 76 77>;
interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty",
"saif0", "saif1", "i2c0", "i2c1",
"auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
"auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
#dma-cells = <1>;
dma-channels = <16>;
clocks = <&clks 26>;
};
......@@ -692,6 +724,8 @@ lcdif@80030000 {
reg = <0x80030000 0x2000>;
interrupts = <38 86>;
clocks = <&clks 55>;
dmas = <&dma_apbh 13>;
dma-names = "rx";
status = "disabled";
};
......@@ -767,6 +801,8 @@ saif0: saif@80042000 {
reg = <0x80042000 0x2000>;
interrupts = <59 80>;
clocks = <&clks 53>;
dmas = <&dma_apbx 4>;
dma-names = "rx-tx";
fsl,saif-dma-channel = <4>;
status = "disabled";
};
......@@ -781,6 +817,8 @@ saif1: saif@80046000 {
reg = <0x80046000 0x2000>;
interrupts = <58 81>;
clocks = <&clks 54>;
dmas = <&dma_apbx 5>;
dma-names = "rx-tx";
fsl,saif-dma-channel = <5>;
status = "disabled";
};
......@@ -796,6 +834,8 @@ lradc@80050000 {
spdif@80054000 {
reg = <0x80054000 0x2000>;
interrupts = <45 66>;
dmas = <&dma_apbx 2>;
dma-names = "tx";
status = "disabled";
};
......@@ -812,6 +852,8 @@ i2c0: i2c@80058000 {
reg = <0x80058000 0x2000>;
interrupts = <111 68>;
clock-frequency = <100000>;
dmas = <&dma_apbx 6>;
dma-names = "rx-tx";
fsl,i2c-dma-channel = <6>;
status = "disabled";
};
......@@ -823,6 +865,8 @@ i2c1: i2c@8005a000 {
reg = <0x8005a000 0x2000>;
interrupts = <110 69>;
clock-frequency = <100000>;
dmas = <&dma_apbx 7>;
dma-names = "rx-tx";
fsl,i2c-dma-channel = <7>;
status = "disabled";
};
......@@ -847,6 +891,8 @@ auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
fsl,auart-dma-channel = <8 9>;
clocks = <&clks 45>;
status = "disabled";
......@@ -856,6 +902,8 @@ auart1: serial@8006c000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006c000 0x2000>;
interrupts = <113 72 73>;
dmas = <&dma_apbx 10>, <&dma_apbx 11>;
dma-names = "rx", "tx";
clocks = <&clks 45>;
status = "disabled";
};
......@@ -864,6 +912,8 @@ auart2: serial@8006e000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006e000 0x2000>;
interrupts = <114 74 75>;
dmas = <&dma_apbx 12>, <&dma_apbx 13>;
dma-names = "rx", "tx";
clocks = <&clks 45>;
status = "disabled";
};
......@@ -872,6 +922,8 @@ auart3: serial@80070000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x80070000 0x2000>;
interrupts = <115 76 77>;
dmas = <&dma_apbx 14>, <&dma_apbx 15>;
dma-names = "rx", "tx";
clocks = <&clks 45>;
status = "disabled";
};
......@@ -880,6 +932,8 @@ auart4: serial@80072000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x80072000 0x2000>;
interrupts = <116 78 79>;
dmas = <&dma_apbx 0>, <&dma_apbx 1>;
dma-names = "rx", "tx";
clocks = <&clks 45>;
status = "disabled";
};
......@@ -943,8 +997,8 @@ mac0: ethernet@800f0000 {
compatible = "fsl,imx28-fec";
reg = <0x800f0000 0x4000>;
interrupts = <101>;
clocks = <&clks 57>, <&clks 57>;
clock-names = "ipg", "ahb";
clocks = <&clks 57>, <&clks 57>, <&clks 64>;
clock-names = "ipg", "ahb", "enet_out";
status = "disabled";
};
......
......@@ -65,9 +65,13 @@ soc {
interrupt-parent = <&intc>;
ranges;
dma-apbh@00110000 {
dma_apbh: dma-apbh@00110000 {
compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
reg = <0x00110000 0x2000>;
interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
#dma-cells = <1>;
dma-channels = <4>;
clocks = <&clks 106>;
};
......@@ -83,6 +87,8 @@ gpmi: gpmi-nand@00112000 {
<&clks 150>, <&clks 149>;
clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
"gpmi_bch_apb", "per1_bch";
dmas = <&dma_apbh 0>;
dma-names = "rx-tx";
fsl,gpmi-dma-channel = <0>;
status = "disabled";
};
......
......@@ -22,7 +22,6 @@
#include <linux/irqchip.h>
#include <linux/irqchip/mxs.h>
#include <linux/micrel_phy.h>
#include <linux/mxsfb.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
......@@ -59,106 +58,6 @@ static inline void __mxs_togl(u32 mask, void __iomem *reg)
__raw_writel(mask, reg + MXS_TOG_ADDR);
}
static struct fb_videomode mx23evk_video_modes[] = {
{
.name = "Samsung-LMS430HF02",
.refresh = 60,
.xres = 480,
.yres = 272,
.pixclock = 108096, /* picosecond (9.2 MHz) */
.left_margin = 15,
.right_margin = 8,
.upper_margin = 12,
.lower_margin = 4,
.hsync_len = 1,
.vsync_len = 1,
},
};
static struct fb_videomode mx28evk_video_modes[] = {
{
.name = "Seiko-43WVF1G",
.refresh = 60,
.xres = 800,
.yres = 480,
.pixclock = 29851, /* picosecond (33.5 MHz) */
.left_margin = 89,
.right_margin = 164,
.upper_margin = 23,
.lower_margin = 10,
.hsync_len = 10,
.vsync_len = 10,
},
};
static struct fb_videomode m28evk_video_modes[] = {
{
.name = "Ampire AM-800480R2TMQW-T01H",
.refresh = 60,
.xres = 800,
.yres = 480,
.pixclock = 30066, /* picosecond (33.26 MHz) */
.left_margin = 0,
.right_margin = 256,
.upper_margin = 0,
.lower_margin = 45,
.hsync_len = 1,
.vsync_len = 1,
},
};
static struct fb_videomode apx4devkit_video_modes[] = {
{
.name = "HannStar PJ70112A",
.refresh = 60,
.xres = 800,
.yres = 480,
.pixclock = 33333, /* picosecond (30.00 MHz) */
.left_margin = 88,
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 13,
.hsync_len = 48,
.vsync_len = 3,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
},
};
static struct fb_videomode apf28dev_video_modes[] = {
{
.name = "LW700",
.refresh = 60,
.xres = 800,
.yres = 480,
.pixclock = 30303, /* picosecond */
.left_margin = 96,
.right_margin = 96, /* at least 3 & 1 */
.upper_margin = 0x14,
.lower_margin = 0x15,
.hsync_len = 64,
.vsync_len = 4,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
},
};
static struct fb_videomode cfa10049_video_modes[] = {
{
.name = "Himax HX8357-B",
.refresh = 60,
.xres = 320,
.yres = 480,
.pixclock = 108506, /* picosecond (9.216 MHz) */
.left_margin = 2,
.right_margin = 2,
.upper_margin = 2,
.lower_margin = 2,
.hsync_len = 15,
.vsync_len = 15,
},
};
static struct mxsfb_platform_data mxsfb_pdata __initdata;
/*
* MX28EVK_FLEXCAN_SWITCH is shared between both flexcan controllers
*/
......@@ -189,8 +88,6 @@ static void mx28evk_flexcan1_switch(int enable)
static struct flexcan_platform_data flexcan_pdata[2];
static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("fsl,imx23-lcdif", 0x80030000, NULL, &mxsfb_pdata),
OF_DEV_AUXDATA("fsl,imx28-lcdif", 0x80030000, NULL, &mxsfb_pdata),
OF_DEV_AUXDATA("fsl,imx28-flexcan", 0x80032000, NULL, &flexcan_pdata[0]),
OF_DEV_AUXDATA("fsl,imx28-flexcan", 0x80034000, NULL, &flexcan_pdata[1]),
{ /* sentinel */ }
......@@ -340,16 +237,6 @@ static void __init update_fec_mac_prop(enum mac_oui oui)
}
}
static void __init imx23_evk_init(void)
{
mxsfb_pdata.mode_list = mx23evk_video_modes;
mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes);
mxsfb_pdata.default_bpp = 32;
mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
MXSFB_SYNC_DOTCLK_FAILING_ACT;
}
static inline void enable_clk_enet_out(void)
{
struct clk *clk = clk_get_sys("enet_out", NULL);
......@@ -360,16 +247,8 @@ static inline void enable_clk_enet_out(void)
static void __init imx28_evk_init(void)
{
enable_clk_enet_out();
update_fec_mac_prop(OUI_FSL);
mxsfb_pdata.mode_list = mx28evk_video_modes;
mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes);
mxsfb_pdata.default_bpp = 32;
mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
MXSFB_SYNC_DOTCLK_FAILING_ACT;
mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
}
......@@ -382,20 +261,6 @@ static void __init imx28_evk_post_init(void)
}
}
static void __init m28evk_init(void)
{
mxsfb_pdata.mode_list = m28evk_video_modes;
mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes);
mxsfb_pdata.default_bpp = 16;
mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
}
static void __init sc_sps1_init(void)
{
enable_clk_enet_out();
}
static int apx4devkit_phy_fixup(struct phy_device *phy)
{
phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
......@@ -409,13 +274,6 @@ static void __init apx4devkit_init(void)
if (IS_BUILTIN(CONFIG_PHYLIB))
phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
apx4devkit_phy_fixup);
mxsfb_pdata.mode_list = apx4devkit_video_modes;
mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes);
mxsfb_pdata.default_bpp = 32;
mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
MXSFB_SYNC_DOTCLK_FAILING_ACT;
}
#define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0)
......@@ -494,52 +352,24 @@ static void __init tx28_post_init(void)
static void __init cfa10049_init(void)
{
enable_clk_enet_out();
update_fec_mac_prop(OUI_CRYSTALFONTZ);
mxsfb_pdata.mode_list = cfa10049_video_modes;
mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
mxsfb_pdata.default_bpp = 32;
mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
}
static void __init cfa10037_init(void)
{
enable_clk_enet_out();
update_fec_mac_prop(OUI_CRYSTALFONTZ);
}
static void __init apf28_init(void)
{
enable_clk_enet_out();
mxsfb_pdata.mode_list = apf28dev_video_modes;
mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes);
mxsfb_pdata.default_bpp = 16;
mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT;
mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
MXSFB_SYNC_DOTCLK_FAILING_ACT;
}
static void __init mxs_machine_init(void)
{
if (of_machine_is_compatible("fsl,imx28-evk"))
imx28_evk_init();
else if (of_machine_is_compatible("fsl,imx23-evk"))
imx23_evk_init();
else if (of_machine_is_compatible("denx,m28evk"))
m28evk_init();
else if (of_machine_is_compatible("bluegiga,apx4devkit"))
apx4devkit_init();
else if (of_machine_is_compatible("crystalfontz,cfa10037"))
cfa10037_init();
else if (of_machine_is_compatible("crystalfontz,cfa10049"))
cfa10049_init();
else if (of_machine_is_compatible("armadeus,imx28-apf28"))
apf28_init();
else if (of_machine_is_compatible("schulercontrol,imx28-sps1"))
sc_sps1_init();
of_platform_populate(NULL, of_default_bus_match_table,
mxs_auxdata_lookup, NULL);
......
......@@ -27,6 +27,7 @@
#include <linux/stmp_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <asm/irq.h>
......@@ -139,6 +140,8 @@ struct mxs_dma_engine {
struct dma_device dma_device;
struct device_dma_parameters dma_parms;
struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
struct platform_device *pdev;
unsigned int nr_channels;
};
struct mxs_dma_type {
......@@ -350,9 +353,7 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int ret;
if (!data)
return -EINVAL;
if (data)
mxs_chan->chan_irq = data->chan_irq;
mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev,
......@@ -665,8 +666,55 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
return ret;
}
struct mxs_dma_filter_param {
struct device_node *of_node;
unsigned int chan_id;
};
static bool mxs_dma_filter_fn(struct dma_chan *chan, void *fn_param)
{
struct mxs_dma_filter_param *param = fn_param;
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_irq;
if (mxs_dma->dma_device.dev->of_node != param->of_node)
return false;
if (chan->chan_id != param->chan_id)
return false;
chan_irq = platform_get_irq(mxs_dma->pdev, param->chan_id);
if (chan_irq < 0)
return false;
mxs_chan->chan_irq = chan_irq;
return true;
}
struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
struct mxs_dma_engine *mxs_dma = ofdma->of_dma_data;
dma_cap_mask_t mask = mxs_dma->dma_device.cap_mask;
struct mxs_dma_filter_param param;
if (dma_spec->args_count != 1)
return NULL;
param.of_node = ofdma->of_node;
param.chan_id = dma_spec->args[0];
if (param.chan_id >= mxs_dma->nr_channels)
return NULL;
return dma_request_channel(mask, mxs_dma_filter_fn, &param);
}
static int __init mxs_dma_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const struct platform_device_id *id_entry;
const struct of_device_id *of_id;
const struct mxs_dma_type *dma_type;
......@@ -674,10 +722,16 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
struct resource *iores;
int ret, i;
mxs_dma = kzalloc(sizeof(*mxs_dma), GFP_KERNEL);
mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL);
if (!mxs_dma)
return -ENOMEM;
ret = of_property_read_u32(np, "dma-channels", &mxs_dma->nr_channels);
if (ret) {
dev_err(&pdev->dev, "failed to read dma-channels\n");
return ret;
}
of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev);
if (of_id)
id_entry = of_id->data;
......@@ -689,24 +743,13 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
mxs_dma->dev_id = dma_type->id;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mxs_dma->base = devm_ioremap_resource(&pdev->dev, iores);
if (IS_ERR(mxs_dma->base))
return PTR_ERR(mxs_dma->base);
if (!request_mem_region(iores->start, resource_size(iores),
pdev->name)) {
ret = -EBUSY;
goto err_request_region;
}
mxs_dma->base = ioremap(iores->start, resource_size(iores));
if (!mxs_dma->base) {
ret = -ENOMEM;
goto err_ioremap;
}
mxs_dma->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(mxs_dma->clk)) {
ret = PTR_ERR(mxs_dma->clk);
goto err_clk;
}
mxs_dma->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(mxs_dma->clk))
return PTR_ERR(mxs_dma->clk);
dma_cap_set(DMA_SLAVE, mxs_dma->dma_device.cap_mask);
dma_cap_set(DMA_CYCLIC, mxs_dma->dma_device.cap_mask);
......@@ -732,8 +775,9 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
ret = mxs_dma_init(mxs_dma);
if (ret)
goto err_init;
return ret;
mxs_dma->pdev = pdev;
mxs_dma->dma_device.dev = &pdev->dev;
/* mxs_dma gets 65535 bytes maximum sg size */
......@@ -751,22 +795,19 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
ret = dma_async_device_register(&mxs_dma->dma_device);
if (ret) {
dev_err(mxs_dma->dma_device.dev, "unable to register\n");
goto err_init;
return ret;
}
ret = of_dma_controller_register(np, mxs_dma_xlate, mxs_dma);
if (ret) {
dev_err(mxs_dma->dma_device.dev,
"failed to register controller\n");
dma_async_device_unregister(&mxs_dma->dma_device);
}
dev_info(mxs_dma->dma_device.dev, "initialized\n");
return 0;
err_init:
clk_put(mxs_dma->clk);
err_clk:
iounmap(mxs_dma->base);
err_ioremap:
release_mem_region(iores->start, resource_size(iores));
err_request_region:
kfree(mxs_dma);
return ret;
}
static struct platform_driver mxs_dma_driver = {
......
......@@ -31,7 +31,6 @@
#include <linux/of_i2c.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/fsl/mxs-dma.h>
#define DRIVER_NAME "mxs-i2c"
......@@ -113,9 +112,7 @@ struct mxs_i2c_dev {
uint32_t timing1;
/* DMA support components */
int dma_channel;
struct dma_chan *dmach;
struct mxs_dma_data dma_data;
uint32_t pio_data[2];
uint32_t addr_data;
struct scatterlist sg_io[2];
......@@ -518,21 +515,6 @@ static const struct i2c_algorithm mxs_i2c_algo = {
.functionality = mxs_i2c_func,
};
static bool mxs_i2c_dma_filter(struct dma_chan *chan, void *param)
{
struct mxs_i2c_dev *i2c = param;
if (!mxs_dma_is_apbx(chan))
return false;
if (chan->chan_id != i2c->dma_channel)
return false;
chan->private = &i2c->dma_data;
return true;
}
static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed)
{
/* The I2C block clock run at 24MHz */
......@@ -577,17 +559,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
struct device_node *node = dev->of_node;
int ret;
/*
* 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(node, "fsl,i2c-dma-channel",
&i2c->dma_channel);
if (ret) {
dev_err(dev, "Failed to get DMA channel!\n");
return -ENODEV;
}
ret = of_property_read_u32(node, "clock-frequency", &speed);
if (ret) {
dev_warn(dev, "No I2C speed selected, using 100kHz\n");
......@@ -607,8 +578,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
struct pinctrl *pinctrl;
struct resource *res;
resource_size_t res_size;
int err, irq, dmairq;
dma_cap_mask_t mask;
int err, irq;
pinctrl = devm_pinctrl_get_select_default(dev);
if (IS_ERR(pinctrl))
......@@ -620,9 +590,8 @@ static int mxs_i2c_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
dmairq = platform_get_irq(pdev, 1);
if (!res || irq < 0 || dmairq < 0)
if (!res || irq < 0)
return -ENOENT;
res_size = resource_size(res);
......@@ -648,10 +617,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
}
/* Setup the DMA */
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
i2c->dma_data.chan_irq = dmairq;
i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
i2c->dmach = dma_request_slave_channel(dev, "rx-tx");
if (!i2c->dmach) {
dev_err(dev, "Failed to request dma\n");
return -ENODEV;
......
......@@ -548,22 +548,6 @@ static const struct mmc_host_ops mxs_mmc_ops = {
.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
};
static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
{
struct mxs_mmc_host *host = param;
struct mxs_ssp *ssp = &host->ssp;
if (!mxs_dma_is_apbh(chan))
return false;
if (chan->chan_id != ssp->dma_channel)
return false;
chan->private = &ssp->dma_data;
return true;
}
static struct platform_device_id mxs_ssp_ids[] = {
{
.name = "imx23-mmc",
......@@ -591,20 +575,17 @@ static int mxs_mmc_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct mxs_mmc_host *host;
struct mmc_host *mmc;
struct resource *iores, *dmares;
struct resource *iores;
struct pinctrl *pinctrl;
int ret = 0, irq_err, irq_dma;
dma_cap_mask_t mask;
int ret = 0, irq_err;
struct regulator *reg_vmmc;
enum of_gpio_flags flags;
struct mxs_ssp *ssp;
u32 bus_width = 0;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
irq_err = platform_get_irq(pdev, 0);
irq_dma = platform_get_irq(pdev, 1);
if (!iores || irq_err < 0 || irq_dma < 0)
if (!iores || irq_err < 0)
return -EINVAL;
mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
......@@ -620,23 +601,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
goto out_mmc_free;
}
if (np) {
ssp->devid = (enum mxs_ssp_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",
&ssp->dma_channel);
if (ret) {
dev_err(mmc_dev(host->mmc),
"failed to get dma channel\n");
goto out_mmc_free;
}
} else {
ssp->devid = pdev->id_entry->driver_data;
ssp->dma_channel = dmares->start;
}
host->mmc = mmc;
host->sdio_irq_en = 0;
......@@ -666,10 +631,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
mxs_mmc_reset(host);
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
ssp->dma_data.chan_irq = irq_dma;
ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host);
ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx");
if (!ssp->dmach) {
dev_err(mmc_dev(host->mmc),
"%s: failed to request dma\n", __func__);
......
......@@ -36,7 +36,6 @@
#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand"
#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch"
#define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch"
#define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma"
/* add our owner bbt descriptor */
static uint8_t scan_ff_pattern[] = { 0xff };
......@@ -420,28 +419,6 @@ static void release_bch_irq(struct gpmi_nand_data *this)
free_irq(i, this);
}
static bool gpmi_dma_filter(struct dma_chan *chan, void *param)
{
struct gpmi_nand_data *this = param;
int dma_channel = (int)this->private;
if (!mxs_dma_is_apbh(chan))
return false;
/*
* only catch the GPMI dma channels :
* for mx23 : MX23_DMA_GPMI0 ~ MX23_DMA_GPMI3
* (These four channels share the same IRQ!)
*
* for mx28 : MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7
* (These eight channels share the same IRQ!)
*/
if (dma_channel == chan->chan_id) {
chan->private = &this->dma_data;
return true;
}
return false;
}
static void release_dma_channels(struct gpmi_nand_data *this)
{
unsigned int i;
......@@ -455,36 +432,10 @@ static void release_dma_channels(struct gpmi_nand_data *this)
static int acquire_dma_channels(struct gpmi_nand_data *this)
{
struct platform_device *pdev = this->pdev;
struct resource *r_dma;
struct device_node *dn;
u32 dma_channel;
int ret;
struct dma_chan *dma_chan;
dma_cap_mask_t mask;
/* dma channel, we only use the first one. */
dn = pdev->dev.of_node;
ret = of_property_read_u32(dn, "fsl,gpmi-dma-channel", &dma_channel);
if (ret) {
pr_err("unable to get DMA channel from dt.\n");
goto acquire_err;
}
this->private = (void *)dma_channel;
/* gpmi dma interrupt */
r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
GPMI_NAND_DMA_INTERRUPT_RES_NAME);
if (!r_dma) {
pr_err("Can't get resource for DMA\n");
goto acquire_err;
}
this->dma_data.chan_irq = r_dma->start;
/* request dma channel */
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
if (!dma_chan) {
pr_err("Failed to request DMA channel.\n");
goto acquire_err;
......
......@@ -20,7 +20,7 @@
#include <linux/mtd/nand.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/fsl/mxs-dma.h>
#include <linux/dmaengine.h>
#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
struct resources {
......@@ -180,7 +180,6 @@ struct gpmi_nand_data {
/* DMA channels */
#define DMA_CHANS 8
struct dma_chan *dma_chans[DMA_CHANS];
struct mxs_dma_data dma_data;
enum dma_ops_type last_dma_type;
enum dma_ops_type dma_type;
struct completion dma_done;
......
......@@ -1802,17 +1802,22 @@ fec_probe(struct platform_device *pdev)
goto failed_clk;
}
/* enet_out is optional, depends on board */
fep->clk_enet_out = devm_clk_get(&pdev->dev, "enet_out");
if (IS_ERR(fep->clk_enet_out))
fep->clk_enet_out = NULL;
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
fep->bufdesc_ex =
pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
if (IS_ERR(fep->clk_ptp)) {
ret = PTR_ERR(fep->clk_ptp);
fep->clk_ptp = NULL;
fep->bufdesc_ex = 0;
}
clk_prepare_enable(fep->clk_ahb);
clk_prepare_enable(fep->clk_ipg);
if (!IS_ERR(fep->clk_ptp))
clk_prepare_enable(fep->clk_enet_out);
clk_prepare_enable(fep->clk_ptp);
reg_phy = devm_regulator_get(&pdev->dev, "phy");
......@@ -1878,7 +1883,7 @@ fec_probe(struct platform_device *pdev)
failed_regulator:
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
if (!IS_ERR(fep->clk_ptp))
clk_disable_unprepare(fep->clk_enet_out);
clk_disable_unprepare(fep->clk_ptp);
failed_pin:
failed_clk:
......@@ -1905,6 +1910,7 @@ fec_drv_remove(struct platform_device *pdev)
clk_disable_unprepare(fep->clk_ptp);
if (fep->ptp_clock)
ptp_clock_unregister(fep->ptp_clock);
clk_disable_unprepare(fep->clk_enet_out);
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
for (i = 0; i < FEC_IRQ_NUM; i++) {
......@@ -1935,6 +1941,7 @@ fec_suspend(struct device *dev)
fec_stop(ndev);
netif_device_detach(ndev);
}
clk_disable_unprepare(fep->clk_enet_out);
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
......@@ -1947,6 +1954,7 @@ fec_resume(struct device *dev)
struct net_device *ndev = dev_get_drvdata(dev);
struct fec_enet_private *fep = netdev_priv(ndev);
clk_prepare_enable(fep->clk_enet_out);
clk_prepare_enable(fep->clk_ahb);
clk_prepare_enable(fep->clk_ipg);
if (netif_running(ndev)) {
......
......@@ -207,6 +207,7 @@ struct fec_enet_private {
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_enet_out;
struct clk *clk_ptp;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
......
......@@ -490,21 +490,6 @@ static int mxs_spi_transfer_one(struct spi_master *master,
return status;
}
static bool mxs_ssp_dma_filter(struct dma_chan *chan, void *param)
{
struct mxs_ssp *ssp = param;
if (!mxs_dma_is_apbh(chan))
return false;
if (chan->chan_id != ssp->dma_channel)
return false;
chan->private = &ssp->dma_data;
return true;
}
static const struct of_device_id mxs_spi_dt_ids[] = {
{ .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, },
{ .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, },
......@@ -520,13 +505,12 @@ static int mxs_spi_probe(struct platform_device *pdev)
struct spi_master *master;
struct mxs_spi *spi;
struct mxs_ssp *ssp;
struct resource *iores, *dmares;
struct resource *iores;
struct pinctrl *pinctrl;
struct clk *clk;
void __iomem *base;
int devid, dma_channel, clk_freq;
int ret = 0, irq_err, irq_dma;
dma_cap_mask_t mask;
int devid, clk_freq;
int ret = 0, irq_err;
/*
* Default clock speed for the SPI core. 160MHz seems to
......@@ -537,8 +521,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq_err = platform_get_irq(pdev, 0);
irq_dma = platform_get_irq(pdev, 1);
if (!iores || irq_err < 0 || irq_dma < 0)
if (!iores || irq_err < 0)
return -EINVAL;
base = devm_ioremap_resource(&pdev->dev, iores);
......@@ -553,32 +536,11 @@ static int mxs_spi_probe(struct platform_device *pdev)
if (IS_ERR(clk))
return PTR_ERR(clk);
if (np) {
devid = (enum mxs_ssp_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",
&dma_channel);
if (ret) {
dev_err(&pdev->dev,
"Failed to get DMA channel\n");
return -EINVAL;
}
ret = of_property_read_u32(np, "clock-frequency",
&clk_freq);
if (ret)
clk_freq = clk_freq_default;
} else {
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (!dmares)
return -EINVAL;
devid = pdev->id_entry->driver_data;
dma_channel = dmares->start;
clk_freq = clk_freq_default;
}
master = spi_alloc_master(&pdev->dev, sizeof(*spi));
if (!master)
......@@ -597,7 +559,6 @@ static int mxs_spi_probe(struct platform_device *pdev)
ssp->clk = clk;
ssp->base = base;
ssp->devid = devid;
ssp->dma_channel = dma_channel;
init_completion(&spi->c);
......@@ -606,10 +567,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
if (ret)
goto out_master_free;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
ssp->dma_data.chan_irq = irq_dma;
ssp->dmach = dma_request_channel(mask, mxs_ssp_dma_filter, ssp);
ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx");
if (!ssp->dmach) {
dev_err(ssp->dev, "Failed to request DMA\n");
goto out_master_free;
......
......@@ -35,7 +35,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/of_device.h>
#include <linux/dma-mapping.h>
#include <linux/fsl/mxs-dma.h>
#include <linux/dmaengine.h>
#include <asm/cacheflush.h>
......@@ -148,11 +148,6 @@ struct mxs_auart_port {
struct device *dev;
/* for DMA */
struct mxs_dma_data dma_data;
int dma_channel_rx, dma_channel_tx;
int dma_irq_rx, dma_irq_tx;
int dma_channel;
struct scatterlist tx_sgl;
struct dma_chan *tx_dma_chan;
void *tx_dma_buf;
......@@ -440,20 +435,6 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u)
return mctrl;
}
static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
{
struct mxs_auart_port *s = param;
if (!mxs_dma_is_apbx(chan))
return false;
if (s->dma_channel == chan->chan_id) {
chan->private = &s->dma_data;
return true;
}
return false;
}
static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s);
static void dma_rx_callback(void *arg)
{
......@@ -545,21 +526,11 @@ static void mxs_auart_dma_exit(struct mxs_auart_port *s)
static int mxs_auart_dma_init(struct mxs_auart_port *s)
{
dma_cap_mask_t mask;
if (auart_dma_enabled(s))
return 0;
/* We do not get the right DMA channels. */
if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1)
return -EINVAL;
/* init for RX */
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
s->dma_channel = s->dma_channel_rx;
s->dma_data.chan_irq = s->dma_irq_rx;
s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx");
if (!s->rx_dma_chan)
goto err_out;
s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
......@@ -567,9 +538,7 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s)
goto err_out;
/* init for TX */
s->dma_channel = s->dma_channel_tx;
s->dma_data.chan_irq = s->dma_irq_tx;
s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx");
if (!s->tx_dma_chan)
goto err_out;
s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
......@@ -1020,7 +989,6 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
u32 dma_channel[2];
int ret;
if (!np)
......@@ -1034,20 +1002,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
}
s->port.line = ret;
s->dma_irq_rx = platform_get_irq(pdev, 1);
s->dma_irq_tx = platform_get_irq(pdev, 2);
ret = of_property_read_u32_array(np, "fsl,auart-dma-channel",
dma_channel, 2);
if (ret == 0) {
s->dma_channel_rx = dma_channel[0];
s->dma_channel_tx = dma_channel[1];
s->flags |= MXS_AUART_DMA_CONFIG;
} else {
s->dma_channel_rx = -1;
s->dma_channel_tx = -1;
}
return 0;
}
......
......@@ -2437,6 +2437,8 @@ config FB_MXS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_MODE_HELPERS
select OF_VIDEOMODE
help
Framebuffer support for the MXS SoC.
......
......@@ -42,13 +42,15 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <video/of_display_timing.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/pinctrl/consumer.h>
#include <linux/mxsfb.h>
#include <linux/fb.h>
#include <linux/regulator/consumer.h>
#include <video/videomode.h>
#define REG_SET 4
#define REG_CLR 8
......@@ -107,7 +109,7 @@
#define VDCTRL0_ENABLE_PRESENT (1 << 28)
#define VDCTRL0_VSYNC_ACT_HIGH (1 << 27)
#define VDCTRL0_HSYNC_ACT_HIGH (1 << 26)
#define VDCTRL0_DOTCLK_ACT_FAILING (1 << 25)
#define VDCTRL0_DOTCLK_ACT_FALLING (1 << 25)
#define VDCTRL0_ENABLE_ACT_HIGH (1 << 24)
#define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
......@@ -142,6 +144,14 @@
#define BLUE 2
#define TRANSP 3
#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */
#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */
enum mxsfb_devtype {
MXSFB_V3,
MXSFB_V4,
......@@ -168,8 +178,8 @@ struct mxsfb_info {
unsigned ld_intf_width;
unsigned dotclk_delay;
const struct mxsfb_devdata *devdata;
int mapped;
u32 sync;
struct regulator *reg_lcd;
};
#define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
......@@ -329,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
{
struct mxsfb_info *host = to_imxfb_host(fb_info);
u32 reg;
int ret;
dev_dbg(&host->pdev->dev, "%s\n", __func__);
if (host->reg_lcd) {
ret = regulator_enable(host->reg_lcd);
if (ret) {
dev_err(&host->pdev->dev,
"lcd regulator enable failed: %d\n", ret);
return;
}
}
clk_prepare_enable(host->clk);
clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
......@@ -353,6 +373,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
struct mxsfb_info *host = to_imxfb_host(fb_info);
unsigned loop;
u32 reg;
int ret;
dev_dbg(&host->pdev->dev, "%s\n", __func__);
......@@ -376,6 +397,13 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
clk_disable_unprepare(host->clk);
host->enabled = 0;
if (host->reg_lcd) {
ret = regulator_disable(host->reg_lcd);
if (ret)
dev_err(&host->pdev->dev,
"lcd regulator disable failed: %d\n", ret);
}
}
static int mxsfb_set_par(struct fb_info *fb_info)
......@@ -459,8 +487,8 @@ static int mxsfb_set_par(struct fb_info *fb_info)
vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
if (host->sync & MXSFB_SYNC_DOTCLK_FAILING_ACT)
vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING;
if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
writel(vdctrl0, host->base + LCDC_VDCTRL0);
......@@ -679,14 +707,105 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
return 0;
}
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
{
struct fb_info *fb_info = &host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
struct device *dev = &host->pdev->dev;
struct device_node *np = host->pdev->dev.of_node;
struct device_node *display_np;
struct device_node *timings_np;
struct display_timings *timings;
u32 width;
int i;
int ret = 0;
display_np = of_parse_phandle(np, "display", 0);
if (!display_np) {
dev_err(dev, "failed to find display phandle\n");
return -ENOENT;
}
ret = of_property_read_u32(display_np, "bus-width", &width);
if (ret < 0) {
dev_err(dev, "failed to get property bus-width\n");
goto put_display_node;
}
switch (width) {
case 8:
host->ld_intf_width = STMLCDIF_8BIT;
break;
case 16:
host->ld_intf_width = STMLCDIF_16BIT;
break;
case 18:
host->ld_intf_width = STMLCDIF_18BIT;
break;
case 24:
host->ld_intf_width = STMLCDIF_24BIT;
break;
default:
dev_err(dev, "invalid bus-width value\n");
ret = -EINVAL;
goto put_display_node;
}
ret = of_property_read_u32(display_np, "bits-per-pixel",
&var->bits_per_pixel);
if (ret < 0) {
dev_err(dev, "failed to get property bits-per-pixel\n");
goto put_display_node;
}
timings = of_get_display_timings(display_np);
if (!timings) {
dev_err(dev, "failed to get display timings\n");
ret = -ENOENT;
goto put_display_node;
}
timings_np = of_find_node_by_name(display_np,
"display-timings");
if (!timings_np) {
dev_err(dev, "failed to find display-timings node\n");
ret = -ENOENT;
goto put_display_node;
}
for (i = 0; i < of_get_child_count(timings_np); i++) {
struct videomode vm;
struct fb_videomode fb_vm;
ret = videomode_from_timing(timings, &vm, i);
if (ret < 0)
goto put_timings_node;
ret = fb_videomode_from_videomode(&vm, &fb_vm);
if (ret < 0)
goto put_timings_node;
if (vm.data_flags & DISPLAY_FLAGS_DE_HIGH)
host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
if (vm.data_flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
fb_add_videomode(&fb_vm, &fb_info->modelist);
}
put_timings_node:
of_node_put(timings_np);
put_display_node:
of_node_put(display_np);
return ret;
}
static int mxsfb_init_fbinfo(struct mxsfb_info *host)
{
struct fb_info *fb_info = &host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
struct mxsfb_platform_data *pdata = host->pdev->dev.platform_data;
dma_addr_t fb_phys;
void *fb_virt;
unsigned fb_size = pdata->fb_size;
unsigned fb_size;
int ret;
fb_info->fbops = &mxsfb_ops;
fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
......@@ -696,40 +815,22 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
fb_info->fix.accel = FB_ACCEL_NONE;
var->bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16;
ret = mxsfb_init_fbinfo_dt(host);
if (ret)
return ret;
var->nonstd = 0;
var->activate = FB_ACTIVATE_NOW;
var->accel_flags = 0;
var->vmode = FB_VMODE_NONINTERLACED;
host->dotclk_delay = pdata->dotclk_delay;
host->ld_intf_width = pdata->ld_intf_width;
/* Memory allocation for framebuffer */
if (pdata->fb_phys) {
if (!fb_size)
return -EINVAL;
fb_phys = pdata->fb_phys;
if (!request_mem_region(fb_phys, fb_size, host->pdev->name))
return -ENOMEM;
fb_virt = ioremap(fb_phys, fb_size);
if (!fb_virt) {
release_mem_region(fb_phys, fb_size);
return -ENOMEM;
}
host->mapped = 1;
} else {
if (!fb_size)
fb_size = SZ_2M; /* default */
fb_size = SZ_2M;
fb_virt = alloc_pages_exact(fb_size, GFP_DMA);
if (!fb_virt)
return -ENOMEM;
fb_phys = virt_to_phys(fb_virt);
}
fb_info->fix.smem_start = fb_phys;
fb_info->screen_base = fb_virt;
......@@ -745,13 +846,7 @@ static void mxsfb_free_videomem(struct mxsfb_info *host)
{
struct fb_info *fb_info = &host->fb_info;
if (host->mapped) {
iounmap(fb_info->screen_base);
release_mem_region(fb_info->fix.smem_start,
fb_info->screen_size);
} else {
free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
}
}
static struct platform_device_id mxsfb_devtype[] = {
......@@ -778,47 +873,35 @@ static int mxsfb_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(mxsfb_dt_ids, &pdev->dev);
struct mxsfb_platform_data *pdata = pdev->dev.platform_data;
struct resource *res;
struct mxsfb_info *host;
struct fb_info *fb_info;
struct fb_modelist *modelist;
struct pinctrl *pinctrl;
int panel_enable;
enum of_gpio_flags flags;
int i, ret;
int ret;
if (of_id)
pdev->id_entry = of_id->data;
if (!pdata) {
dev_err(&pdev->dev, "No platformdata. Giving up\n");
return -ENODEV;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Cannot get memory IO resource\n");
return -ENODEV;
}
if (!request_mem_region(res->start, resource_size(res), pdev->name))
return -EBUSY;
fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev);
if (!fb_info) {
dev_err(&pdev->dev, "Failed to allocate fbdev\n");
ret = -ENOMEM;
goto error_alloc_info;
return -ENOMEM;
}
host = to_imxfb_host(fb_info);
host->base = ioremap(res->start, resource_size(res));
if (!host->base) {
host->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(host->base)) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
goto error_ioremap;
ret = PTR_ERR(host->base);
goto fb_release;
}
host->pdev = pdev;
......@@ -829,47 +912,31 @@ static int mxsfb_probe(struct platform_device *pdev)
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl)) {
ret = PTR_ERR(pinctrl);
goto error_getpin;
goto fb_release;
}
host->clk = clk_get(&host->pdev->dev, NULL);
host->clk = devm_clk_get(&host->pdev->dev, NULL);
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
goto error_getclock;
goto fb_release;
}
panel_enable = of_get_named_gpio_flags(pdev->dev.of_node,
"panel-enable-gpios", 0, &flags);
if (gpio_is_valid(panel_enable)) {
unsigned long f = GPIOF_OUT_INIT_HIGH;
if (flags == OF_GPIO_ACTIVE_LOW)
f = GPIOF_OUT_INIT_LOW;
ret = devm_gpio_request_one(&pdev->dev, panel_enable,
f, "panel-enable");
if (ret) {
dev_err(&pdev->dev,
"failed to request gpio %d: %d\n",
panel_enable, ret);
goto error_panel_enable;
}
}
host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
if (IS_ERR(host->reg_lcd))
host->reg_lcd = NULL;
fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
GFP_KERNEL);
if (!fb_info->pseudo_palette) {
ret = -ENOMEM;
goto error_pseudo_pallette;
goto fb_release;
}
INIT_LIST_HEAD(&fb_info->modelist);
host->sync = pdata->sync;
ret = mxsfb_init_fbinfo(host);
if (ret != 0)
goto error_init_fb;
for (i = 0; i < pdata->mode_count; i++)
fb_add_videomode(&pdata->mode_list[i], &fb_info->modelist);
goto fb_release;
modelist = list_first_entry(&fb_info->modelist,
struct fb_modelist, list);
......@@ -883,7 +950,7 @@ static int mxsfb_probe(struct platform_device *pdev)
ret = register_framebuffer(fb_info);
if (ret != 0) {
dev_err(&pdev->dev,"Failed to register framebuffer\n");
goto error_register;
goto fb_destroy;
}
if (!host->enabled) {
......@@ -896,22 +963,12 @@ static int mxsfb_probe(struct platform_device *pdev)
return 0;
error_register:
fb_destroy:
if (host->enabled)
clk_disable_unprepare(host->clk);
fb_destroy_modelist(&fb_info->modelist);
error_init_fb:
kfree(fb_info->pseudo_palette);
error_pseudo_pallette:
error_panel_enable:
clk_put(host->clk);
error_getclock:
error_getpin:
iounmap(host->base);
error_ioremap:
fb_release:
framebuffer_release(fb_info);
error_alloc_info:
release_mem_region(res->start, resource_size(res));
return ret;
}
......@@ -920,19 +977,14 @@ static int mxsfb_remove(struct platform_device *pdev)
{
struct fb_info *fb_info = platform_get_drvdata(pdev);
struct mxsfb_info *host = to_imxfb_host(fb_info);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (host->enabled)
mxsfb_disable_controller(fb_info);
unregister_framebuffer(fb_info);
kfree(fb_info->pseudo_palette);
mxsfb_free_videomem(host);
iounmap(host->base);
clk_put(host->clk);
framebuffer_release(fb_info);
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
......
/*
* 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 __LINUX_MXSFB_H
#define __LINUX_MXSFB_H
#include <linux/fb.h>
#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */
#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
#define MXSFB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */
struct mxsfb_platform_data {
struct fb_videomode *mode_list;
unsigned mode_count;
unsigned default_bpp;
unsigned dotclk_delay; /* refer manual HW_LCDIF_VDCTRL4 register */
unsigned ld_intf_width; /* refer STMLCDIF_* macros */
unsigned fb_size; /* Size of the video memory. If zero a
* default will be used
*/
unsigned long fb_phys; /* physical address for the video memory. If
* zero the framebuffer memory will be dynamically
* allocated. If specified,fb_size must also be specified.
* fb_phys must be unused by Linux.
*/
u32 sync; /* sync mask, contains MXSFB specifics not
* carried in fb_info->var.sync
*/
};
#endif /* __LINUX_MXSFB_H */
......@@ -24,7 +24,7 @@
#ifndef __LINUX_SPI_MXS_SPI_H__
#define __LINUX_SPI_MXS_SPI_H__
#include <linux/fsl/mxs-dma.h>
#include <linux/dmaengine.h>
#define ssp_is_old(host) ((host)->devid == IMX23_SSP)
......@@ -137,9 +137,7 @@ struct mxs_ssp {
unsigned int clk_rate;
enum mxs_ssp_id devid;
int dma_channel;
struct dma_chan *dmach;
struct mxs_dma_data dma_data;
unsigned int dma_dir;
enum dma_transfer_direction slave_dirn;
u32 ssp_pio_words[SSP_PIO_NUM];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment