--- /dev/null
+Frequently asked questions about the sunxi clock system
+=======================================================
+
+This document contains useful bits of information that people tend to ask
+about the sunxi clock system, as well as accompanying ASCII art when adequate.
+
+Q: Why is the main 24MHz oscillator gatable? Wouldn't that break the
+ system?
+
+A: The 24MHz oscillator allows gating to save power. Indeed, if gated
+ carelessly the system would stop functioning, but with the right
+ steps, one can gate it and keep the system running. Consider this
+ simplified suspend example:
+
+ While the system is operational, you would see something like
+
+ 24MHz 32kHz
+ |
+ PLL1
+ \
+ \_ CPU Mux
+ |
+ [CPU]
+
+ When you are about to suspend, you switch the CPU Mux to the 32kHz
+ oscillator:
+
+ 24Mhz 32kHz
+ | |
+ PLL1 |
+ /
+ CPU Mux _/
+ |
+ [CPU]
+
+ Finally you can gate the main oscillator
+
+ 32kHz
+ |
+ |
+ /
+ CPU Mux _/
+ |
+ [CPU]
+
+Q: Were can I learn more about the sunxi clocks?
+
+A: The linux-sunxi wiki contains a page documenting the clock registers,
+ you can find it at
+
+ http://linux-sunxi.org/A10/CCM
+
+ The authoritative source for information at this time is the ccmu driver
+ released by Allwinner, you can find it at
+
+ https://github.com/linux-sunxi/linux-sunxi/tree/sunxi-3.0/arch/arm/mach-sun4i/clock/ccmu
};
Below is a matrix detailing which clk_ops are mandatory based upon the
-hardware capbilities of that clock. A cell marked as "y" means
+hardware capabilities of that clock. A cell marked as "y" means
mandatory, a cell marked as "n" implies that either including that
-callback is invalid or otherwise uneccesary. Empty cells are either
+callback is invalid or otherwise unnecessary. Empty cells are either
optional or must be evaluated on a case-by-case basis.
clock hardware characteristics
Required properties:
- compatible : Should be "ti,omap3-l3-smx" for OMAP3 family
Should be "ti,omap4-l3-noc" for OMAP4 family
+- reg: Contains L3 register address range for each noc domain.
- ti,hwmods: "l3_main_1", ... One hwmod for each noc domain.
Examples:
OMAP Timer bindings
Required properties:
-- compatible: Must be "ti,omap2-timer" for OMAP2+ controllers.
+- compatible: Should be set to one of the below. Please note that
+ OMAP44xx devices have timer instances that are 100%
+ register compatible with OMAP3xxx devices as well as
+ newer timers that are not 100% register compatible.
+ So for OMAP44xx devices timer instances may use
+ different compatible strings.
+
+ ti,omap2420-timer (applicable to OMAP24xx devices)
+ ti,omap3430-timer (applicable to OMAP3xxx/44xx devices)
+ ti,omap4430-timer (applicable to OMAP44xx devices)
+ ti,omap5430-timer (applicable to OMAP543x devices)
+ ti,am335x-timer (applicable to AM335x devices)
+ ti,am335x-timer-1ms (applicable to AM335x devices)
+
- reg: Contains timer register address range (base address and
length).
- interrupts: Contains the interrupt information for the timer. The
Example:
timer12: timer@48304000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48304000 0x400>;
interrupts = <95>;
ti,hwmods = "timer12"
NVIDIA Tegra Power Management Controller (PMC)
-Properties:
+The PMC block interacts with an external Power Management Unit. The PMC
+mostly controls the entry and exit of the system from different sleep
+modes. It provides power-gating controllers for SoC and CPU power-islands.
+
+Required properties:
- name : Should be pmc
- compatible : Should contain "nvidia,tegra<chip>-pmc".
- reg : Offset and length of the register set for the device
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+ "pclk" (The Tegra clock of that name),
+ "clk32k_in" (The 32KHz clock input to Tegra).
+
+Optional properties:
- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
The PMU is an external Power Management Unit, whose interrupt output
signal is fed into the PMC. This signal is optionally inverted, and then
fed into the ARM GIC. The PMC is not involved in the detection or
handling of this interrupt signal, merely its inversion.
+- nvidia,suspend-mode : The suspend mode that the platform should use.
+ Valid values are 0, 1 and 2:
+ 0 (LP0): CPU + Core voltage off and DRAM in self-refresh
+ 1 (LP1): CPU voltage off and DRAM in self-refresh
+ 2 (LP2): CPU voltage off
+- nvidia,core-power-req-active-high : Boolean, core power request active-high
+- nvidia,sys-clock-req-active-high : Boolean, system clock request active-high
+- nvidia,combined-power-req : Boolean, combined power request for CPU & Core
+- nvidia,cpu-pwr-good-en : Boolean, CPU power good signal (from PMIC to PMC)
+ is enabled.
+
+Required properties when nvidia,suspend-mode is specified:
+- nvidia,cpu-pwr-good-time : CPU power good time in uS.
+- nvidia,cpu-pwr-off-time : CPU power off time in uS.
+- nvidia,core-pwr-good-time : <Oscillator-stable-time Power-stable-time>
+ Core power good time in uS.
+- nvidia,core-pwr-off-time : Core power off time in uS.
+
+Required properties when nvidia,suspend-mode=<0>:
+- nvidia,lp0-vec : <start length> Starting address and length of LP0 vector
+ The LP0 vector contains the warm boot code that is executed by AVP when
+ resuming from the LP0 state. The AVP (Audio-Video Processor) is an ARM7
+ processor and always being the first boot processor when chip is power on
+ or resume from deep sleep mode. When the system is resumed from the deep
+ sleep mode, the warm boot code will restore some PLLs, clocks and then
+ bring up CPU0 for resuming the system.
Example:
+/ SoC dts including file
pmc@7000f400 {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car 110>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <1>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <100>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <458>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ nvidia,lp0-vec = <0xbdffd000 0x2000>;
+};
+
+/ Tegra board dts file
+{
+ ...
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+ ...
};
--- /dev/null
+Binding for the axi-clkgen clock generator
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be "adi,axi-clkgen".
+- #clock-cells : from common clock binding; Should always be set to 0.
+- reg : Address and length of the axi-clkgen register set.
+- clocks : Phandle and clock specifier for the parent clock.
+
+Optional properties:
+- clock-output-names : From common clock binding.
+
+Example:
+ clock@0xff000000 {
+ compatible = "adi,axi-clkgen";
+ #clock-cells = <0>;
+ reg = <0xff000000 0x1000>;
+ clocks = <&osc 1>;
+ };
--- /dev/null
+NVIDIA Tegra114 Clock And Reset Controller
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
+for muxing and gating Tegra's clocks, and setting their rates.
+
+Required properties :
+- compatible : Should be "nvidia,tegra114-car"
+- reg : Should contain CAR registers location and length
+- clocks : Should contain phandle and clock specifiers for two clocks:
+ the 32 KHz "32k_in", and the board-specific oscillator "osc".
+- #clock-cells : Should be 1.
+ In clock consumers, this cell represents the clock ID exposed by the CAR.
+
+ The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ this case, those clocks are assigned IDs above 160 in order to highlight
+ this issue. Implementations that interpret these clock IDs as bit values
+ within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ explicitly handle these special cases.
+
+ The balance of the clocks controlled by the CAR are assigned IDs of 160 and
+ above.
+
+ 0 unassigned
+ 1 unassigned
+ 2 unassigned
+ 3 unassigned
+ 4 rtc
+ 5 timer
+ 6 uarta
+ 7 unassigned (register bit affects uartb and vfir)
+ 8 unassigned
+ 9 sdmmc2
+ 10 unassigned (register bit affects spdif_in and spdif_out)
+ 11 i2s1
+ 12 i2c1
+ 13 ndflash
+ 14 sdmmc1
+ 15 sdmmc4
+ 16 unassigned
+ 17 pwm
+ 18 i2s2
+ 19 epp
+ 20 unassigned (register bit affects vi and vi_sensor)
+ 21 2d
+ 22 usbd
+ 23 isp
+ 24 3d
+ 25 unassigned
+ 26 disp2
+ 27 disp1
+ 28 host1x
+ 29 vcp
+ 30 i2s0
+ 31 unassigned
+
+ 32 unassigned
+ 33 unassigned
+ 34 apbdma
+ 35 unassigned
+ 36 kbc
+ 37 unassigned
+ 38 unassigned
+ 39 unassigned (register bit affects fuse and fuse_burn)
+ 40 kfuse
+ 41 sbc1
+ 42 nor
+ 43 unassigned
+ 44 sbc2
+ 45 unassigned
+ 46 sbc3
+ 47 i2c5
+ 48 dsia
+ 49 unassigned
+ 50 mipi
+ 51 hdmi
+ 52 csi
+ 53 unassigned
+ 54 i2c2
+ 55 uartc
+ 56 mipi-cal
+ 57 emc
+ 58 usb2
+ 59 usb3
+ 60 msenc
+ 61 vde
+ 62 bsea
+ 63 bsev
+
+ 64 unassigned
+ 65 uartd
+ 66 unassigned
+ 67 i2c3
+ 68 sbc4
+ 69 sdmmc3
+ 70 unassigned
+ 71 owr
+ 72 afi
+ 73 csite
+ 74 unassigned
+ 75 unassigned
+ 76 la
+ 77 trace
+ 78 soc_therm
+ 79 dtv
+ 80 ndspeed
+ 81 i2cslow
+ 82 dsib
+ 83 tsec
+ 84 unassigned
+ 85 unassigned
+ 86 unassigned
+ 87 unassigned
+ 88 unassigned
+ 89 xusb_host
+ 90 unassigned
+ 91 msenc
+ 92 csus
+ 93 unassigned
+ 94 unassigned
+ 95 unassigned (bit affects xusb_dev and xusb_dev_src)
+
+ 96 unassigned
+ 97 unassigned
+ 98 unassigned
+ 99 mselect
+ 100 tsensor
+ 101 i2s3
+ 102 i2s4
+ 103 i2c4
+ 104 sbc5
+ 105 sbc6
+ 106 d_audio
+ 107 apbif
+ 108 dam0
+ 109 dam1
+ 110 dam2
+ 111 hda2codec_2x
+ 112 unassigned
+ 113 audio0_2x
+ 114 audio1_2x
+ 115 audio2_2x
+ 116 audio3_2x
+ 117 audio4_2x
+ 118 spdif_2x
+ 119 actmon
+ 120 extern1
+ 121 extern2
+ 122 extern3
+ 123 unassigned
+ 124 unassigned
+ 125 hda
+ 126 unassigned
+ 127 se
+
+ 128 hda2hdmi
+ 129 unassigned
+ 130 unassigned
+ 131 unassigned
+ 132 unassigned
+ 133 unassigned
+ 134 unassigned
+ 135 unassigned
+ 136 unassigned
+ 137 unassigned
+ 138 unassigned
+ 139 unassigned
+ 140 unassigned
+ 141 unassigned
+ 142 unassigned
+ 143 unassigned (bit affects xusb_falcon_src, xusb_fs_src,
+ xusb_host_src and xusb_ss_src)
+ 144 cilab
+ 145 cilcd
+ 146 cile
+ 147 dsialp
+ 148 dsiblp
+ 149 unassigned
+ 150 dds
+ 151 unassigned
+ 152 dp2
+ 153 amx
+ 154 adx
+ 155 unassigned (bit affects dfll_ref and dfll_soc)
+ 156 xusb_ss
+
+ 192 uartb
+ 193 vfir
+ 194 spdif_in
+ 195 spdif_out
+ 196 vi
+ 197 vi_sensor
+ 198 fuse
+ 199 fuse_burn
+ 200 clk_32k
+ 201 clk_m
+ 202 clk_m_div2
+ 203 clk_m_div4
+ 204 pll_ref
+ 205 pll_c
+ 206 pll_c_out1
+ 207 pll_c2
+ 208 pll_c3
+ 209 pll_m
+ 210 pll_m_out1
+ 211 pll_p
+ 212 pll_p_out1
+ 213 pll_p_out2
+ 214 pll_p_out3
+ 215 pll_p_out4
+ 216 pll_a
+ 217 pll_a_out0
+ 218 pll_d
+ 219 pll_d_out0
+ 220 pll_d2
+ 221 pll_d2_out0
+ 222 pll_u
+ 223 pll_u_480M
+ 224 pll_u_60M
+ 225 pll_u_48M
+ 226 pll_u_12M
+ 227 pll_x
+ 228 pll_x_out0
+ 229 pll_re_vco
+ 230 pll_re_out
+ 231 pll_e_out0
+ 232 spdif_in_sync
+ 233 i2s0_sync
+ 234 i2s1_sync
+ 235 i2s2_sync
+ 236 i2s3_sync
+ 237 i2s4_sync
+ 238 vimclk_sync
+ 239 audio0
+ 240 audio1
+ 241 audio2
+ 242 audio3
+ 243 audio4
+ 244 spdif
+ 245 clk_out_1
+ 246 clk_out_2
+ 247 clk_out_3
+ 248 blink
+ 252 xusb_host_src
+ 253 xusb_falcon_src
+ 254 xusb_fs_src
+ 255 xusb_ss_src
+ 256 xusb_dev_src
+ 257 xusb_dev
+ 258 xusb_hs_src
+ 259 sclk
+ 260 hclk
+ 261 pclk
+ 262 cclk_g
+ 263 cclk_lp
+ 264 dfll_ref
+ 265 dfll_soc
+
+Example SoC include file:
+
+/ {
+ tegra_car: clock {
+ compatible = "nvidia,tegra114-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ usb@c5004000 {
+ clocks = <&tegra_car 58>; /* usb2 */
+ };
+};
+
+Example board file:
+
+/ {
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+
+ clk_32k: clock@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ &tegra_car {
+ clocks = <&clk_32k> <&osc>;
+ };
+};
90 clk_d
91 unassigned
92 sus
- 93 cdev1
- 94 cdev2
+ 93 cdev2
+ 94 cdev1
95 unassigned
96 uart2
--- /dev/null
+Device Tree Clock bindings for arch-sunxi
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+ "allwinner,sun4i-osc-clk" - for a gatable oscillator
+ "allwinner,sun4i-pll1-clk" - for the main PLL clock
+ "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
+ "allwinner,sun4i-axi-clk" - for the AXI clock
+ "allwinner,sun4i-ahb-clk" - for the AHB clock
+ "allwinner,sun4i-apb0-clk" - for the APB0 clock
+ "allwinner,sun4i-apb1-clk" - for the APB1 clock
+ "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
+
+Required properties for all clocks:
+- reg : shall be the control register address for the clock.
+- clocks : shall be the input parent clock(s) phandle for the clock
+- #clock-cells : from common clock binding; shall be set to 0.
+
+For example:
+
+osc24M: osc24M@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-osc-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&osc24M_fixed>;
+};
+
+pll1: pll1@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+};
+
+cpu: cpu@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-cpu-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>;
+};
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";
};
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:
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>;
+ };
+ };
+ };
};
- "ti,omap2-gpio" for OMAP2 controllers
- "ti,omap3-gpio" for OMAP3 controllers
- "ti,omap4-gpio" for OMAP4 controllers
+- gpio-controller : Marks the device node as a GPIO controller.
- #gpio-cells : Should be two.
- first cell is the pin number
- second cell is used to specify optional parameters (unused)
-- gpio-controller : Marks the device node as a GPIO controller.
+- interrupt-controller: Mark the device node as an interrupt controller.
- #interrupt-cells : Should be 2.
-- interrupt-controller: Mark the device node as an interrupt controller
The first cell is the GPIO number.
The second cell is used to specify flags:
bits[3:0] trigger type and level flags:
gpio4: gpio4 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio4";
- #gpio-cells = <2>;
gpio-controller;
- #interrupt-cells = <2>;
+ #gpio-cells = <2>;
interrupt-controller;
+ #interrupt-cells = <2>;
};
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:
#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";
};
--- /dev/null
+NVIDIA Tegra20/Tegra30/Tegra114 I2C controller driver.
+
+Required properties:
+- compatible : should be:
+ "nvidia,tegra114-i2c"
+ "nvidia,tegra30-i2c"
+ "nvidia,tegra20-i2c"
+ "nvidia,tegra20-i2c-dvc"
+ Details of compatible are as follows:
+ nvidia,tegra20-i2c-dvc: Tegra20 has specific I2C controller called as DVC I2C
+ controller. This only support master mode of I2C communication. Register
+ interface/offset and interrupts handling are different than generic I2C
+ controller. Driver of DVC I2C controller is only compatible with
+ "nvidia,tegra20-i2c-dvc".
+ nvidia,tegra20-i2c: Tegra20 has 4 generic I2C controller. This can support
+ master and slave mode of I2C communication. The i2c-tegra driver only
+ support master mode of I2C communication. Driver of I2C controller is
+ only compatible with "nvidia,tegra20-i2c".
+ nvidia,tegra30-i2c: Tegra30 has 5 generic I2C controller. This controller is
+ very much similar to Tegra20 I2C controller with additional feature:
+ Continue Transfer Support. This feature helps to implement M_NO_START
+ as per I2C core API transfer flags. Driver of I2C controller is
+ compatible with "nvidia,tegra30-i2c" to enable the continue transfer
+ support. This is also compatible with "nvidia,tegra20-i2c" without
+ continue transfer support.
+ nvidia,tegra114-i2c: Tegra114 has 5 generic I2C controller. This controller is
+ very much similar to Tegra30 I2C controller with some hardware
+ modification:
+ - Tegra30/Tegra20 I2C controller has 2 clock source called div-clk and
+ fast-clk. Tegra114 has only one clock source called as div-clk and
+ hence clock mechanism is changed in I2C controller.
+ - Tegra30/Tegra20 I2C controller has enabled per packet transfer by
+ default and there is no way to disable it. Tegra114 has this
+ interrupt disable by default and SW need to enable explicitly.
+ Due to above changes, Tegra114 I2C driver makes incompatible with
+ previous hardware driver. Hence, tegra114 I2C controller is compatible
+ with "nvidia,tegra114-i2c".
+- reg: Should contain I2C controller registers physical address and length.
+- interrupts: Should contain I2C controller interrupts.
+- address-cells: Address cells for I2C device address.
+- size-cells: Size of the I2C device address.
+- clocks: Clock ID as per
+ Documentation/devicetree/bindings/clock/tegra<chip-id>.txt
+ for I2C controller.
+- clock-names: Name of the clock:
+ Tegra20/Tegra30 I2C controller: "div-clk and "fast-clk".
+ Tegra114 I2C controller: "div-clk".
+
+Example:
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <0 38 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 12>, <&tegra_car 124>;
+ clock-names = "div-clk", "fast-clk";
+ status = "disabled";
+ };
--- /dev/null
+* TI Highspeed MMC host controller for DaVinci
+
+The Highspeed MMC Host Controller on TI DaVinci family
+provides an interface for MMC, SD and SDIO types of memory cards.
+
+This file documents the properties used by the davinci_mmc driver.
+
+Required properties:
+- compatible:
+ Should be "ti,da830-mmc": for da830, da850, dm365
+ Should be "ti,dm355-mmc": for dm355, dm644x
+
+Optional properties:
+- bus-width: Number of data lines, can be <1>, <4>, or <8>, default <1>
+- max-frequency: Maximum operating clock frequency, default 25MHz.
+- dmas: List of DMA specifiers with the controller specific format
+ as described in the generic DMA client binding. A tx and rx
+ specifier is required.
+- dma-names: RX and TX DMA request names. These strings correspond
+ 1:1 with the DMA specifiers listed in dmas.
+
+Example:
+mmc0: mmc@1c40000 {
+ compatible = "ti,da830-mmc",
+ reg = <0x40000 0x1000>;
+ interrupts = <16>;
+ status = "okay";
+ bus-width = <4>;
+ max-frequency = <50000000>;
+ dmas = <&edma 16
+ &edma 17>;
+ dma-names = "rx", "tx";
+};
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>;
};
- 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
#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 {
...
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 {
Required properties:
- compatible : "nvidia,tegra-audio-alc5632"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+ "pll_a" (The Tegra clock of that name),
+ "pll_a_out0" (The Tegra clock of that name),
+ "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&alc5632>;
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
Required properties:
- compatible : "nvidia,tegra-audio-trimslice"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+ "pll_a" (The Tegra clock of that name),
+ "pll_a_out0" (The Tegra clock of that name),
+ "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,i2s-controller : The phandle of the Tegra I2S1 controller
- nvidia,audio-codec : The phandle of the WM8903 audio codec
compatible = "nvidia,tegra-audio-trimslice";
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&codec>;
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
Required properties:
- compatible : "nvidia,tegra-audio-wm8753"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+ "pll_a" (The Tegra clock of that name),
+ "pll_a_out0" (The Tegra clock of that name),
+ "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
nvidia,i2s-controller = <&i2s1>;
nvidia,audio-codec = <&wm8753>;
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
Required properties:
- compatible : "nvidia,tegra-audio-wm8903"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+ "pll_a" (The Tegra clock of that name),
+ "pll_a_out0" (The Tegra clock of that name),
+ "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
Required properties:
- compatible : "nvidia,tegra-audio-wm9712"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+ "pll_a" (The Tegra clock of that name),
+ "pll_a_out0" (The Tegra clock of that name),
+ "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
- nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
"Mic", "MIC1";
nvidia,ac97-controller = <&ac97>;
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
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.
#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";
};
--- /dev/null
+Davinci SPI controller device bindings
+
+Required properties:
+- #address-cells: number of cells required to define a chip select
+ address on the SPI bus. Should be set to 1.
+- #size-cells: should be zero.
+- compatible:
+ - "ti,dm6441-spi" for SPI used similar to that on DM644x SoC family
+ - "ti,da830-spi" for SPI used similar to that on DA8xx SoC family
+- reg: Offset and length of SPI controller register space
+- num-cs: Number of chip selects
+- ti,davinci-spi-intr-line: interrupt line used to connect the SPI
+ IP to the interrupt controller within the SoC. Possible values
+ are 0 and 1. Manual says one of the two possible interrupt
+ lines can be tied to the interrupt controller. Set this
+ based on a specifc SoC configuration.
+- interrupts: interrupt number mapped to CPU.
+- clocks: spi clk phandle
+
+Example of a NOR flash slave device (n25q032) connected to DaVinci
+SPI controller device over the SPI bus.
+
+spi0:spi@20BF0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,dm6446-spi";
+ reg = <0x20BF0000 0x1000>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <338>;
+ clocks = <&clkspi>;
+
+ flash: n25q032@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "test";
+ reg = <0x80000 0x380000>;
+ };
+ };
+};
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"
represents PERIPHERAL.
- power : Should be "50". This signifies the controller can supply upto
100mA when operating in host mode.
+ - usb-phy : the phandle for the PHY device
Optional properties:
- ctrl-module : phandle of the control module this glue uses to write to
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select CLKSRC_OF
select COMMON_CLK
select GENERIC_CLOCKEVENTS
select HAVE_CLK_PREPARE
select MULTI_IRQ_HANDLER
select PINCTRL
select SPARSE_IRQ
+ select STMP_DEVICE
select USE_OF
help
Support for Freescale MXS-based family of processors
select PINCTRL_DOVE
select PLAT_ORION_LEGACY
select USB_ARCH_HAS_EHCI
+ select MVEBU_MBUS
help
Support for the Marvell Dove SoC 88AP510
select PINCTRL
select PINCTRL_KIRKWOOD
select PLAT_ORION_LEGACY
+ select MVEBU_MBUS
help
Support for the following Marvell Kirkwood series SoCs:
88F6180, 88F6192 and 88F6281.
select GENERIC_CLOCKEVENTS
select PCI
select PLAT_ORION_LEGACY
+ select MVEBU_MBUS
help
Support for the following Marvell MV78xx0 series SoCs:
MV781x0, MV782x0.
select GENERIC_CLOCKEVENTS
select PCI
select PLAT_ORION_LEGACY
+ select MVEBU_MBUS
help
Support for the following Marvell Orion 5x series SoCs:
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
select HAVE_CLK
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
+ select SOC_BUS
select SPARSE_IRQ
select USE_OF
help
config HAVE_ARM_TWD
bool
depends on SMP
+ select CLKSRC_OF if OF
help
This options enables support for the ARM timer and watchdog unit
imx28-tx28.dtb
dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb
dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
+ omap3430-sdp.dtb \
omap3-beagle.dtb \
+ omap3-devkit8000.dtb \
omap3-beagle-xm.dtb \
omap3-evm.dtb \
omap3-tobi.dtb \
+ omap3-igep0020.dtb \
+ omap3-igep0030.dtb \
omap4-panda.dtb \
omap4-panda-a4.dtb \
omap4-panda-es.dtb \
status = "okay";
};
- i2c1: i2c@44e0b000 {
+ i2c0: i2c@44e0b000 {
status = "okay";
clock-frequency = <400000>;
led@2 {
label = "beaglebone:green:heartbeat";
- gpios = <&gpio2 21 0>;
+ gpios = <&gpio1 21 0>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
led@3 {
label = "beaglebone:green:mmc0";
- gpios = <&gpio2 22 0>;
+ gpios = <&gpio1 22 0>;
linux,default-trigger = "mmc0";
default-state = "off";
};
led@4 {
label = "beaglebone:green:usr2";
- gpios = <&gpio2 23 0>;
+ gpios = <&gpio1 23 0>;
default-state = "off";
};
led@5 {
label = "beaglebone:green:usr3";
- gpios = <&gpio2 24 0>;
+ gpios = <&gpio1 24 0>;
default-state = "off";
};
};
status = "okay";
};
- i2c1: i2c@44e0b000 {
+ i2c0: i2c@44e0b000 {
status = "okay";
clock-frequency = <400000>;
};
};
- i2c2: i2c@4802a000 {
+ i2c1: i2c@4802a000 {
status = "okay";
clock-frequency = <100000>;
debounce-delay-ms = <5>;
col-scan-delay-us = <2>;
- row-gpios = <&gpio2 25 0 /* Bank1, pin25 */
- &gpio2 26 0 /* Bank1, pin26 */
- &gpio2 27 0>; /* Bank1, pin27 */
+ row-gpios = <&gpio1 25 0 /* Bank1, pin25 */
+ &gpio1 26 0 /* Bank1, pin26 */
+ &gpio1 27 0>; /* Bank1, pin27 */
- col-gpios = <&gpio2 21 0 /* Bank1, pin21 */
- &gpio2 22 0>; /* Bank1, pin22 */
+ col-gpios = <&gpio1 21 0 /* Bank1, pin21 */
+ &gpio1 22 0>; /* Bank1, pin22 */
linux,keymap = <0x0000008b /* MENU */
0x0100009e /* BACK */
switch@9 {
label = "volume-up";
linux,code = <115>;
- gpios = <&gpio1 2 1>;
+ gpios = <&gpio0 2 1>;
gpio-key,wakeup;
};
switch@10 {
label = "volume-down";
linux,code = <114>;
- gpios = <&gpio1 3 1>;
+ gpios = <&gpio0 3 1>;
gpio-key,wakeup;
};
};
status = "okay";
};
- i2c1: i2c@44e0b000 {
+ i2c0: i2c@44e0b000 {
status = "okay";
clock-frequency = <400000>;
led@1 {
label = "evmsk:green:usr0";
- gpios = <&gpio2 4 0>;
+ gpios = <&gpio1 4 0>;
default-state = "off";
};
led@2 {
label = "evmsk:green:usr1";
- gpios = <&gpio2 5 0>;
+ gpios = <&gpio1 5 0>;
default-state = "off";
};
led@3 {
label = "evmsk:green:mmc0";
- gpios = <&gpio2 6 0>;
+ gpios = <&gpio1 6 0>;
linux,default-trigger = "mmc0";
default-state = "off";
};
led@4 {
label = "evmsk:green:heartbeat";
- gpios = <&gpio2 7 0>;
+ gpios = <&gpio1 7 0>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
switch@1 {
label = "button0";
linux,code = <0x100>;
- gpios = <&gpio3 3 0>;
+ gpios = <&gpio2 3 0>;
};
switch@2 {
label = "button1";
linux,code = <0x101>;
- gpios = <&gpio3 2 0>;
+ gpios = <&gpio2 2 0>;
};
switch@3 {
label = "button2";
linux,code = <0x102>;
- gpios = <&gpio1 30 0>;
+ gpios = <&gpio0 30 0>;
gpio-key,wakeup;
};
switch@4 {
label = "button3";
linux,code = <0x103>;
- gpios = <&gpio3 5 0>;
+ gpios = <&gpio2 5 0>;
};
};
};
serial3 = &uart4;
serial4 = &uart5;
serial5 = &uart6;
+ d_can0 = &dcan0;
+ d_can1 = &dcan1;
};
cpus {
reg = <0x48200000 0x1000>;
};
- gpio1: gpio@44e07000 {
+ gpio0: gpio@44e07000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio1";
gpio-controller;
interrupts = <96>;
};
- gpio2: gpio@4804c000 {
+ gpio1: gpio@4804c000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio2";
gpio-controller;
interrupts = <98>;
};
- gpio3: gpio@481ac000 {
+ gpio2: gpio@481ac000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio3";
gpio-controller;
interrupts = <32>;
};
- gpio4: gpio@481ae000 {
+ gpio3: gpio@481ae000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio4";
gpio-controller;
status = "disabled";
};
- i2c1: i2c@44e0b000 {
+ i2c0: i2c@44e0b000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
- i2c2: i2c@4802a000 {
+ i2c1: i2c@4802a000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
- i2c3: i2c@4819c000 {
+ i2c2: i2c@4819c000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
dcan0: d_can@481cc000 {
compatible = "bosch,d_can";
ti,hwmods = "d_can0";
- reg = <0x481cc000 0x2000>;
+ reg = <0x481cc000 0x2000
+ 0x44e10644 0x4>;
interrupts = <52>;
status = "disabled";
};
dcan1: d_can@481d0000 {
compatible = "bosch,d_can";
ti,hwmods = "d_can1";
- reg = <0x481d0000 0x2000>;
+ reg = <0x481d0000 0x2000
+ 0x44e10644 0x4>;
interrupts = <55>;
status = "disabled";
};
timer1: timer@44e31000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer-1ms";
reg = <0x44e31000 0x400>;
interrupts = <67>;
ti,hwmods = "timer1";
};
timer2: timer@48040000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer";
reg = <0x48040000 0x400>;
interrupts = <68>;
ti,hwmods = "timer2";
};
timer3: timer@48042000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer";
reg = <0x48042000 0x400>;
interrupts = <69>;
ti,hwmods = "timer3";
};
timer4: timer@48044000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer";
reg = <0x48044000 0x400>;
interrupts = <92>;
ti,hwmods = "timer4";
};
timer5: timer@48046000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer";
reg = <0x48046000 0x400>;
interrupts = <93>;
ti,hwmods = "timer5";
};
timer6: timer@48048000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer";
reg = <0x48048000 0x400>;
interrupts = <94>;
ti,hwmods = "timer6";
};
timer7: timer@4804a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,am335x-timer";
reg = <0x4804a000 0x400>;
interrupts = <95>;
ti,hwmods = "timer7";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x48030000 0x400>;
- interrupt = <65>;
+ interrupts = <65>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi0";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x481a0000 0x400>;
- interrupt = <125>;
+ interrupts = <125>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi1";
status = "disabled";
*/
/dts-v1/;
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
/ {
model = "TI AM3517 EVM (AM3517/05)";
*/
/dts-v1/;
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
/ {
model = "TeeJet Mt.Ventoux";
};
soc {
- serial@d0012000 {
- clock-frequency = <200000000>;
- status = "okay";
- };
- sata@d00a0000 {
- nr-ports = <2>;
- status = "okay";
- };
+ internal-regs {
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "okay";
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
};
- phy1: ethernet-phy@1 {
- reg = <1>;
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
};
- };
- ethernet@d0070000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0074000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "rgmii-id";
- };
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins1>;
+ pinctrl-names = "default";
+ /*
+ * This device is disabled by default, because
+ * using the SD card connector requires
+ * changing the default CON40 connector
+ * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a
+ * different connector
+ * "DB-88F6710_MPP_RGMII_SD_Jumper".
+ */
+ status = "disabled";
+ /* No CD or WP GPIOs */
+ };
- mvsdio@d00d4000 {
- pinctrl-0 = <&sdio_pins1>;
- pinctrl-names = "default";
- /*
- * This device is disabled by default, because
- * using the SD card connector requires
- * changing the default CON40 connector
- * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a
- * different connector
- * "DB-88F6710_MPP_RGMII_SD_Jumper".
- */
- status = "disabled";
- /* No CD or WP GPIOs */
- };
+ usb@50000 {
+ status = "okay";
+ };
- usb@d0050000 {
- status = "okay";
- };
+ usb@51000 {
+ status = "okay";
+ };
- usb@d0051000 {
- status = "okay";
- };
+ spi0: spi@10600 {
+ status = "okay";
- spi0: spi@d0010600 {
- status = "okay";
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mx25l25635e";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+ };
+ };
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "mx25l25635e";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <50000000>;
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * both standard PCIe slots and mini-PCIe
+ * slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
};
};
};
};
soc {
- serial@d0012000 {
- clock-frequency = <200000000>;
- status = "okay";
- };
- timer@d0020300 {
- clock-frequency = <600000000>;
- status = "okay";
- };
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
+ internal-regs {
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "okay";
};
+ timer@20300 {
+ clock-frequency = <600000000>;
+ status = "okay";
+ };
+
+ pinctrl {
+ pwr_led_pin: pwr-led-pin {
+ marvell,pins = "mpp63";
+ marvell,function = "gpo";
+ };
- phy1: ethernet-phy@1 {
- reg = <1>;
+ stat_led_pins: stat-led-pins {
+ marvell,pins = "mpp64", "mpp65";
+ marvell,function = "gpio";
+ };
};
- };
- ethernet@d0070000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0074000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "rgmii-id";
- };
- mvsdio@d00d4000 {
- pinctrl-0 = <&sdio_pins3>;
- pinctrl-names = "default";
- status = "okay";
- /*
- * No CD or WP GPIOs: SDIO interface used for
- * Wifi/Bluetooth chip
- */
- };
+ gpio_leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_led_pin &stat_led_pins>;
- usb@d0050000 {
- status = "okay";
- };
+ green_pwr_led {
+ label = "mirabox:green:pwr";
+ gpios = <&gpio1 31 1>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ blue_stat_led {
+ label = "mirabox:blue:stat";
+ gpios = <&gpio2 0 1>;
+ linux,default-trigger = "cpu0";
+ };
+
+ green_stat_led {
+ label = "mirabox:green:stat";
+ gpios = <&gpio2 1 1>;
+ default-state = "off";
+ };
+ };
+
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins3>;
+ pinctrl-names = "default";
+ status = "okay";
+ /*
+ * No CD or WP GPIOs: SDIO interface used for
+ * Wifi/Bluetooth chip
+ */
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
- usb@d0051000 {
- status = "okay";
+ usb@51000 {
+ status = "okay";
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pca9505: pca9505@25 {
+ compatible = "nxp,pca9505";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x25>;
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected on the PCB to a USB 3.0 XHCI controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ };
};
};
};
};
soc {
- serial@d0012000 {
- clock-frequency = <200000000>;
- status = "okay";
- };
- sata@d00a0000 {
- nr-ports = <2>;
- status = "okay";
- };
+ internal-regs {
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "okay";
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
};
- phy1: ethernet-phy@1 {
- reg = <1>;
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "sgmii";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
};
- };
- ethernet@d0070000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "sgmii";
- };
- ethernet@d0074000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "rgmii-id";
- };
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins1>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ };
- mvsdio@d00d4000 {
- pinctrl-0 = <&sdio_pins1>;
- pinctrl-names = "default";
- status = "okay";
- /* No CD or WP GPIOs */
- };
+ usb@50000 {
+ status = "okay";
+ };
- usb@d0050000 {
- status = "okay";
- };
+ usb@51000 {
+ status = "okay";
+ };
- usb@d0051000 {
- status = "okay";
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button@1 {
+ label = "Software Button";
+ linux,code = <116>;
+ gpios = <&gpio0 6 1>;
+ };
+ };
};
};
-};
+ };
* 370 and Armada XP SoC.
*/
-/include/ "skeleton.dtsi"
+/include/ "skeleton64.dtsi"
/ {
model = "Marvell Armada 370 and XP SoC";
};
};
- mpic: interrupt-controller@d0020000 {
- compatible = "marvell,mpic";
- #interrupt-cells = <1>;
- #size-cells = <1>;
- interrupt-controller;
- };
-
- coherency-fabric@d0020200 {
- compatible = "marvell,coherency-fabric";
- reg = <0xd0020200 0xb0>,
- <0xd0021810 0x1c>;
- };
-
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&mpic>;
- ranges;
+ ranges = <0 0 0xd0000000 0x100000>;
- serial@d0012000 {
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mpic: interrupt-controller@20000 {
+ compatible = "marvell,mpic";
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ };
+
+ coherency-fabric@20200 {
+ compatible = "marvell,coherency-fabric";
+ reg = <0x20200 0xb0>, <0x21810 0x1c>;
+ };
+
+ serial@12000 {
compatible = "snps,dw-apb-uart";
- reg = <0xd0012000 0x100>;
+ reg = <0x12000 0x100>;
reg-shift = <2>;
interrupts = <41>;
reg-io-width = <1>;
status = "disabled";
- };
- serial@d0012100 {
+ };
+ serial@12100 {
compatible = "snps,dw-apb-uart";
- reg = <0xd0012100 0x100>;
+ reg = <0x12100 0x100>;
reg-shift = <2>;
interrupts = <42>;
reg-io-width = <1>;
status = "disabled";
- };
-
- timer@d0020300 {
- compatible = "marvell,armada-370-xp-timer";
- reg = <0xd0020300 0x30>,
- <0xd0021040 0x30>;
- interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
- clocks = <&coreclk 2>;
- };
-
- addr-decoding@d0020000 {
- compatible = "marvell,armada-addr-decoding-controller";
- reg = <0xd0020000 0x258>;
- };
-
- sata@d00a0000 {
- compatible = "marvell,orion-sata";
- reg = <0xd00a0000 0x2400>;
- interrupts = <55>;
- clocks = <&gateclk 15>, <&gateclk 30>;
- clock-names = "0", "1";
- status = "disabled";
- };
+ };
+
+ timer@20300 {
+ compatible = "marvell,armada-370-xp-timer";
+ reg = <0x20300 0x30>, <0x21040 0x30>;
+ interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
+ clocks = <&coreclk 2>;
+ };
+
+ sata@a0000 {
+ compatible = "marvell,orion-sata";
+ reg = <0xa0000 0x2400>;
+ interrupts = <55>;
+ clocks = <&gateclk 15>, <&gateclk 30>;
+ clock-names = "0", "1";
+ status = "disabled";
+ };
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,orion-mdio";
- reg = <0xd0072004 0x4>;
- };
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x72004 0x4>;
+ };
- ethernet@d0070000 {
+ ethernet@70000 {
compatible = "marvell,armada-370-neta";
- reg = <0xd0070000 0x2500>;
+ reg = <0x70000 0x2500>;
interrupts = <8>;
clocks = <&gateclk 4>;
status = "disabled";
- };
+ };
- ethernet@d0074000 {
+ ethernet@74000 {
compatible = "marvell,armada-370-neta";
- reg = <0xd0074000 0x2500>;
+ reg = <0x74000 0x2500>;
interrupts = <10>;
clocks = <&gateclk 3>;
status = "disabled";
- };
-
- i2c0: i2c@d0011000 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0xd0011000 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <31>;
- timeout-ms = <1000>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- i2c1: i2c@d0011100 {
- compatible = "marvell,mv64xxx-i2c";
- reg = <0xd0011100 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <32>;
- timeout-ms = <1000>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- rtc@10300 {
- compatible = "marvell,orion-rtc";
- reg = <0xd0010300 0x20>;
- interrupts = <50>;
- };
-
- mvsdio@d00d4000 {
- compatible = "marvell,orion-sdio";
- reg = <0xd00d4000 0x200>;
- interrupts = <54>;
- clocks = <&gateclk 17>;
- status = "disabled";
- };
-
- usb@d0050000 {
- compatible = "marvell,orion-ehci";
- reg = <0xd0050000 0x500>;
- interrupts = <45>;
- status = "disabled";
- };
-
- usb@d0051000 {
- compatible = "marvell,orion-ehci";
- reg = <0xd0051000 0x500>;
- interrupts = <46>;
- status = "disabled";
- };
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <31>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@11100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <32>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ rtc@10300 {
+ compatible = "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <50>;
+ };
+
+ mvsdio@d4000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0xd4000 0x200>;
+ interrupts = <54>;
+ clocks = <&gateclk 17>;
+ status = "disabled";
+ };
- spi0: spi@d0010600 {
- compatible = "marvell,orion-spi";
- reg = <0xd0010600 0x28>;
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- interrupts = <30>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
+ usb@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x500>;
+ interrupts = <45>;
+ status = "disabled";
+ };
- spi1: spi@d0010680 {
- compatible = "marvell,orion-spi";
- reg = <0xd0010680 0x28>;
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- interrupts = <92>;
- clocks = <&coreclk 0>;
- status = "disabled";
+ usb@51000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x51000 0x500>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10600 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <30>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ compatible = "marvell,orion-spi";
+ reg = <0x10680 0x28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <92>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-bootcs@10400 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <0x10400 0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs0@10408 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <0x10408 0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs1@10410 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <0x10410 0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs2@10418 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <0x10418 0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs3@10420 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <0x10420 0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
};
};
-};
-
+ };
*/
/include/ "armada-370-xp.dtsi"
+/include/ "skeleton.dtsi"
/ {
model = "Marvell Armada 370 family SoC";
compatible = "marvell,armada370", "marvell,armada-370-xp";
- L2: l2-cache {
- compatible = "marvell,aurora-outer-cache";
- reg = <0xd0008000 0x1000>;
- cache-id-part = <0x100>;
- wt-override;
- };
aliases {
gpio0 = &gpio0;
gpio2 = &gpio2;
};
- mpic: interrupt-controller@d0020000 {
- reg = <0xd0020a00 0x1d0>,
- <0xd0021870 0x58>;
- };
-
soc {
- system-controller@d0018200 {
+ ranges = <0 0xd0000000 0x100000>;
+ internal-regs {
+ system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
- reg = <0xd0018200 0x100>;
- };
-
- pinctrl {
- compatible = "marvell,mv88f6710-pinctrl";
- reg = <0xd0018000 0x38>;
-
- sdio_pins1: sdio-pins1 {
- marvell,pins = "mpp9", "mpp11", "mpp12",
- "mpp13", "mpp14", "mpp15";
- marvell,function = "sd0";
+ reg = <0x18200 0x100>;
};
- sdio_pins2: sdio-pins2 {
- marvell,pins = "mpp47", "mpp48", "mpp49",
- "mpp50", "mpp51", "mpp52";
- marvell,function = "sd0";
+ L2: l2-cache {
+ compatible = "marvell,aurora-outer-cache";
+ reg = <0xd0008000 0x1000>;
+ cache-id-part = <0x100>;
+ wt-override;
};
- sdio_pins3: sdio-pins3 {
- marvell,pins = "mpp48", "mpp49", "mpp50",
- "mpp51", "mpp52", "mpp53";
- marvell,function = "sd0";
+ mpic: interrupt-controller@20000 {
+ reg = <0x20a00 0x1d0>, <0x21870 0x58>;
};
- };
-
- gpio0: gpio@d0018100 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018100 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <82>, <83>, <84>, <85>;
- };
- gpio1: gpio@d0018140 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018140 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <87>, <88>, <89>, <90>;
- };
+ pinctrl {
+ compatible = "marvell,mv88f6710-pinctrl";
+ reg = <0x18000 0x38>;
+
+ sdio_pins1: sdio-pins1 {
+ marvell,pins = "mpp9", "mpp11", "mpp12",
+ "mpp13", "mpp14", "mpp15";
+ marvell,function = "sd0";
+ };
+
+ sdio_pins2: sdio-pins2 {
+ marvell,pins = "mpp47", "mpp48", "mpp49",
+ "mpp50", "mpp51", "mpp52";
+ marvell,function = "sd0";
+ };
+
+ sdio_pins3: sdio-pins3 {
+ marvell,pins = "mpp48", "mpp49", "mpp50",
+ "mpp51", "mpp52", "mpp53";
+ marvell,function = "sd0";
+ };
+ };
- gpio2: gpio@d0018180 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018180 0x40>;
- ngpios = <2>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <91>;
- };
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
- coreclk: mvebu-sar@d0018230 {
- compatible = "marvell,armada-370-core-clock";
- reg = <0xd0018230 0x08>;
- #clock-cells = <1>;
- };
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
- gateclk: clock-gating-control@d0018220 {
- compatible = "marvell,armada-370-gating-clock";
- reg = <0xd0018220 0x4>;
- clocks = <&coreclk 0>;
- #clock-cells = <1>;
- };
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <91>;
+ };
- xor@d0060800 {
- compatible = "marvell,orion-xor";
- reg = <0xd0060800 0x100
- 0xd0060A00 0x100>;
- status = "okay";
+ coreclk: mvebu-sar@18230 {
+ compatible = "marvell,armada-370-core-clock";
+ reg = <0x18230 0x08>;
+ #clock-cells = <1>;
+ };
- xor00 {
- interrupts = <51>;
- dmacap,memcpy;
- dmacap,xor;
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-370-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
};
- xor01 {
- interrupts = <52>;
- dmacap,memcpy;
- dmacap,xor;
- dmacap,memset;
+
+ xor@60800 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60800 0x100
+ 0x60A00 0x100>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <51>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <52>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
};
- };
- xor@d0060900 {
- compatible = "marvell,orion-xor";
- reg = <0xd0060900 0x100
- 0xd0060b00 0x100>;
- status = "okay";
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <94>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <95>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
- xor10 {
- interrupts = <94>;
- dmacap,memcpy;
- dmacap,xor;
+ usb@50000 {
+ clocks = <&coreclk 0>;
};
- xor11 {
- interrupts = <95>;
- dmacap,memcpy;
- dmacap,xor;
- dmacap,memset;
+
+ usb@51000 {
+ clocks = <&coreclk 0>;
};
- };
- usb@d0050000 {
- clocks = <&coreclk 0>;
- };
+ thermal@18300 {
+ compatible = "marvell,armada370-thermal";
+ reg = <0x18300 0x4
+ 0x18304 0x4>;
+ status = "okay";
+ };
- usb@d0051000 {
- clocks = <&coreclk 0>;
+ pcie-controller {
+ compatible = "marvell,armada-370-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ reg = <0x40000 0x2000>, <0x80000 0x2000>;
+
+ reg-names = "pcie0.0", "pcie1.0";
+
+ ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
+ 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
+ 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+ };
};
-
};
};
memory {
device_type = "memory";
- reg = <0x00000000 0x80000000>; /* 2 GB */
+ reg = <0 0x00000000 0 0x80000000>; /* 2 GB */
};
soc {
- serial@d0012000 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012100 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012200 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012300 {
- clock-frequency = <250000000>;
- status = "okay";
- };
-
- sata@d00a0000 {
- nr-ports = <2>;
- status = "okay";
- };
-
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
+ internal-regs {
+ serial@12000 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
+ serial@12100 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
+ serial@12200 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
+ serial@12300 {
+ clock-frequency = <250000000>;
+ status = "okay";
};
- phy1: ethernet-phy@1 {
- reg = <1>;
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
};
- phy2: ethernet-phy@2 {
- reg = <25>;
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <25>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <27>;
+ };
};
- phy3: ethernet-phy@3 {
- reg = <27>;
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "sgmii";
+ };
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "sgmii";
};
- };
- ethernet@d0070000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0074000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0030000 {
- status = "okay";
- phy = <&phy2>;
- phy-mode = "sgmii";
- };
- ethernet@d0034000 {
- status = "okay";
- phy = <&phy3>;
- phy-mode = "sgmii";
- };
+ mvsdio@d4000 {
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ };
- mvsdio@d00d4000 {
- pinctrl-0 = <&sdio_pins>;
- pinctrl-names = "default";
- status = "okay";
- /* No CD or WP GPIOs */
- };
+ usb@50000 {
+ status = "okay";
+ };
- usb@d0050000 {
- status = "okay";
- };
+ usb@51000 {
+ status = "okay";
+ };
- usb@d0051000 {
- status = "okay";
- };
+ usb@52000 {
+ status = "okay";
+ };
- usb@d0052000 {
- status = "okay";
- };
+ spi0: spi@10600 {
+ status = "okay";
- spi0: spi@d0010600 {
- status = "okay";
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p64";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <20000000>;
+ };
+ };
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "m25p64";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <20000000>;
+ pcie-controller {
+ status = "okay";
+
+ /*
+ * All 6 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+ pcie@3,0 {
+ /* Port 0, Lane 2 */
+ status = "okay";
+ };
+ pcie@4,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@10,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
};
};
};
memory {
device_type = "memory";
-
/*
- * 4 GB of plug-in RAM modules by default but only 3GB
- * are visible, the amount of memory available can be
- * changed by the bootloader according the size of the
- * module actually plugged
+ * 8 GB of plug-in RAM modules by default.The amount
+ * of memory available can be changed by the
+ * bootloader according the size of the module
+ * actually plugged. Only 7GB are usable because
+ * addresses from 0xC0000000 to 0xffffffff are used by
+ * the internal registers of the SoC.
*/
- reg = <0x00000000 0xC0000000>;
+ reg = <0x00000000 0x00000000 0x00000000 0xC0000000>,
+ <0x00000001 0x00000000 0x00000001 0x00000000>;
};
soc {
- serial@d0012000 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012100 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012200 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012300 {
- clock-frequency = <250000000>;
- status = "okay";
- };
-
- sata@d00a0000 {
- nr-ports = <2>;
- status = "okay";
- };
+ internal-regs {
+ serial@12000 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
+ serial@12100 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
+ serial@12200 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
+ serial@12300 {
+ clock-frequency = <250000000>;
+ status = "okay";
+ };
- mdio {
- phy0: ethernet-phy@0 {
- reg = <16>;
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
};
- phy1: ethernet-phy@1 {
- reg = <17>;
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <16>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <17>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <18>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <19>;
+ };
};
- phy2: ethernet-phy@2 {
- reg = <18>;
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
};
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "rgmii-id";
+ };
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "rgmii-id";
+ };
+
+ spi0: spi@10600 {
+ status = "okay";
- phy3: ethernet-phy@3 {
- reg = <19>;
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
};
- };
- ethernet@d0070000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0074000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0030000 {
- status = "okay";
- phy = <&phy2>;
- phy-mode = "rgmii-id";
- };
- ethernet@d0034000 {
- status = "okay";
- phy = <&phy3>;
- phy-mode = "rgmii-id";
- };
+ devbus-bootcs@10400 {
+ status = "okay";
+ ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf000000, size 0x1000000 */
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 16 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x1000000>;
+ bank-width = <2>;
+ };
+ };
- spi0: spi@d0010600 {
- status = "okay";
+ pcie-controller {
+ status = "okay";
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "n25q128a13";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <108000000>;
+ /*
+ * The 3 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@10,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
};
};
};
};
cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <0>;
- clocks = <&cpuclk 0>;
- };
-
- cpu@1 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <1>;
- clocks = <&cpuclk 1>;
- };
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ };
};
soc {
- pinctrl {
- compatible = "marvell,mv78230-pinctrl";
- reg = <0xd0018000 0x38>;
-
- sdio_pins: sdio-pins {
- marvell,pins = "mpp30", "mpp31", "mpp32",
- "mpp33", "mpp34", "mpp35";
- marvell,function = "sd0";
+ internal-regs {
+ pinctrl {
+ compatible = "marvell,mv78230-pinctrl";
+ reg = <0x18000 0x38>;
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
};
- };
- gpio0: gpio@d0018100 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018100 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <82>, <83>, <84>, <85>;
- };
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <17>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <87>, <88>, <89>;
+ };
- gpio1: gpio@d0018140 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018140 0x40>;
- ngpios = <17>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <87>, <88>, <89>;
+ /*
+ * MV78230 has 2 PCIe units Gen2.0: One unit can be
+ * configured as x4 or quad x1 lanes. One unit is
+ * x4/x1.
+ */
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+#address-cells = <3>;
+#size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */
+ 0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */
+ 0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */
+ 0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
+ 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 59>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 60>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 61>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ pcie@9,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 99>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 26>;
+ status = "disabled";
+ };
+ };
};
};
};
};
cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <0>;
- clocks = <&cpuclk 0>;
- };
-
- cpu@1 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <1>;
- clocks = <&cpuclk 1>;
- };
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ };
};
soc {
- pinctrl {
- compatible = "marvell,mv78260-pinctrl";
- reg = <0xd0018000 0x38>;
-
- sdio_pins: sdio-pins {
- marvell,pins = "mpp30", "mpp31", "mpp32",
- "mpp33", "mpp34", "mpp35";
- marvell,function = "sd0";
+ internal-regs {
+ pinctrl {
+ compatible = "marvell,mv78260-pinctrl";
+ reg = <0x18000 0x38>;
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
};
- };
- gpio0: gpio@d0018100 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018100 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <82>, <83>, <84>, <85>;
- };
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
- gpio1: gpio@d0018140 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018140 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <87>, <88>, <89>, <90>;
- };
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
- gpio2: gpio@d0018180 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018180 0x40>;
- ngpios = <3>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <91>;
- };
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <91>;
+ };
- ethernet@d0034000 {
+ ethernet@34000 {
compatible = "marvell,armada-370-neta";
- reg = <0xd0034000 0x2500>;
+ reg = <0x34000 0x2500>;
interrupts = <14>;
clocks = <&gateclk 1>;
status = "disabled";
+ };
+
+ /*
+ * MV78260 has 3 PCIe units Gen2.0: Two units can be
+ * configured as x4 or quad x1 lanes. One unit is
+ * x4/x1.
+ */
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */
+ 0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */
+ 0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */
+ 0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
+ 0x82000000 0 0x82000 0x82000 0 0x00002000 /* Port 3.0 registers */
+ 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
+ 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 59>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 60>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 61>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ pcie@9,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 99>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 26>;
+ status = "disabled";
+ };
+
+ pcie@10,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x82000 0 0x2000>;
+ reg = <0x5000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 103>;
+ marvell,pcie-port = <3>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 27>;
+ status = "disabled";
+ };
+ };
};
};
};
cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <0>;
- clocks = <&cpuclk 0>;
- };
-
- cpu@1 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <1>;
- clocks = <&cpuclk 1>;
- };
-
- cpu@2 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <2>;
- clocks = <&cpuclk 2>;
- };
-
- cpu@3 {
- device_type = "cpu";
- compatible = "marvell,sheeva-v7";
- reg = <3>;
- clocks = <&cpuclk 3>;
- };
- };
+ #address-cells = <1>;
+ #size-cells = <0>;
- soc {
- pinctrl {
- compatible = "marvell,mv78460-pinctrl";
- reg = <0xd0018000 0x38>;
-
- sdio_pins: sdio-pins {
- marvell,pins = "mpp30", "mpp31", "mpp32",
- "mpp33", "mpp34", "mpp35";
- marvell,function = "sd0";
- };
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
};
- gpio0: gpio@d0018100 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018100 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <82>, <83>, <84>, <85>;
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
};
- gpio1: gpio@d0018140 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018140 0x40>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <87>, <88>, <89>, <90>;
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <2>;
+ clocks = <&cpuclk 2>;
};
- gpio2: gpio@d0018180 {
- compatible = "marvell,orion-gpio";
- reg = <0xd0018180 0x40>;
- ngpios = <3>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupts-cells = <2>;
- interrupts = <91>;
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <3>;
+ clocks = <&cpuclk 3>;
};
+ };
+
+ soc {
+ internal-regs {
+ pinctrl {
+ compatible = "marvell,mv78460-pinctrl";
+ reg = <0x18000 0x38>;
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
+ };
- ethernet@d0034000 {
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
+
+ gpio2: gpio@18180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <91>;
+ };
+
+ ethernet@34000 {
compatible = "marvell,armada-370-neta";
- reg = <0xd0034000 0x2500>;
+ reg = <0x34000 0x2500>;
interrupts = <14>;
clocks = <&gateclk 1>;
status = "disabled";
+ };
+
+ /*
+ * MV78460 has 4 PCIe units Gen2.0: Two units can be
+ * configured as x4 or quad x1 lanes. Two units are
+ * x4/x1.
+ */
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */
+ 0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */
+ 0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */
+ 0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */
+ 0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
+ 0x82000000 0 0x82000 0x82000 0 0x00002000 /* Port 3.0 registers */
+ 0x82000000 0 0x84000 0x84000 0 0x00002000 /* Port 1.1 registers */
+ 0x82000000 0 0x88000 0x88000 0 0x00002000 /* Port 1.2 registers */
+ 0x82000000 0 0x8c000 0x8c000 0 0x00002000 /* Port 1.3 registers */
+ 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
+ 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 59>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 6>;
+ status = "disabled";
+ };
+
+ pcie@3,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 60>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 7>;
+ status = "disabled";
+ };
+
+ pcie@4,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 61>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 8>;
+ status = "disabled";
+ };
+
+ pcie@5,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ reg = <0x2800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 62>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 9>;
+ status = "disabled";
+ };
+
+ pcie@6,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
+ reg = <0x3000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 63>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <1>;
+ clocks = <&gateclk 10>;
+ status = "disabled";
+ };
+
+ pcie@7,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
+ reg = <0x3800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 64>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <2>;
+ clocks = <&gateclk 11>;
+ status = "disabled";
+ };
+
+ pcie@8,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
+ reg = <0x4000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 65>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <3>;
+ clocks = <&gateclk 12>;
+ status = "disabled";
+ };
+ pcie@9,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
+ reg = <0x4800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 99>;
+ marvell,pcie-port = <2>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 26>;
+ status = "disabled";
+ };
+
+ pcie@10,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82005000 0 0x82000 0 0x2000>;
+ reg = <0x5000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 103>;
+ marvell,pcie-port = <3>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 27>;
+ status = "disabled";
+ };
+ };
};
};
- };
+};
memory {
device_type = "memory";
- reg = <0x00000000 0xC0000000>; /* 3 GB */
+ reg = <0 0x00000000 0 0xC0000000>; /* 3 GB */
};
soc {
- serial@d0012000 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- serial@d0012100 {
- clock-frequency = <250000000>;
- status = "okay";
- };
- pinctrl {
- led_pins: led-pins-0 {
- marvell,pins = "mpp49", "mpp51", "mpp53";
- marvell,function = "gpio";
+ internal-regs {
+ serial@12000 {
+ clock-frequency = <250000000>;
+ status = "okay";
};
- };
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&led_pins>;
-
- red_led {
- label = "red_led";
- gpios = <&gpio1 17 1>;
- default-state = "off";
+ serial@12100 {
+ clock-frequency = <250000000>;
+ status = "okay";
};
-
- yellow_led {
- label = "yellow_led";
- gpios = <&gpio1 19 1>;
- default-state = "off";
+ pinctrl {
+ led_pins: led-pins-0 {
+ marvell,pins = "mpp49", "mpp51", "mpp53";
+ marvell,function = "gpio";
+ };
};
-
- green_led {
- label = "green_led";
- gpios = <&gpio1 21 1>;
- default-state = "off";
- linux,default-trigger = "heartbeat";
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ red_led {
+ label = "red_led";
+ gpios = <&gpio1 17 1>;
+ default-state = "off";
+ };
+
+ yellow_led {
+ label = "yellow_led";
+ gpios = <&gpio1 19 1>;
+ default-state = "off";
+ };
+
+ green_led {
+ label = "green_led";
+ gpios = <&gpio1 21 1>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
};
- };
- gpio_keys {
- compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
- button@1 {
- label = "Init Button";
- linux,code = <116>;
- gpios = <&gpio1 28 0>;
+ button@1 {
+ label = "Init Button";
+ linux,code = <116>;
+ gpios = <&gpio1 28 0>;
+ };
};
- };
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
+ mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
- phy2: ethernet-phy@2 {
- reg = <2>;
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
};
- phy3: ethernet-phy@3 {
- reg = <3>;
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "sgmii";
+ };
+ ethernet@74000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "sgmii";
+ };
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "sgmii";
+ };
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "sgmii";
+ };
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+ i2c@11100 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ s35390a: s35390a@30 {
+ compatible = "s35390a";
+ reg = <0x30>;
+ };
+ };
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
+ };
+ usb@50000 {
+ status = "okay";
+ };
+ usb@51000 {
+ status = "okay";
};
- };
- ethernet@d0070000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "sgmii";
- };
- ethernet@d0074000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "sgmii";
- };
- ethernet@d0030000 {
- status = "okay";
- phy = <&phy2>;
- phy-mode = "sgmii";
- };
- ethernet@d0034000 {
- status = "okay";
- phy = <&phy3>;
- phy-mode = "sgmii";
- };
- i2c@d0011000 {
- status = "okay";
- clock-frequency = <400000>;
- };
- i2c@d0011100 {
- status = "okay";
- clock-frequency = <400000>;
+ devbus-bootcs@10400 {
+ status = "okay";
+ ranges = <0 0xf0000000 0x8000000>; /* @addr 0xf000000, size 0x8000000 */
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 128 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x8000000>;
+ bank-width = <2>;
+ };
+ };
- s35390a: s35390a@30 {
- compatible = "s35390a";
- reg = <0x30>;
+ pcie-controller {
+ status = "okay";
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
};
};
- sata@d00a0000 {
- nr-ports = <2>;
- status = "okay";
- };
- usb@d0050000 {
- status = "okay";
- };
- usb@d0051000 {
- status = "okay";
- };
};
};
model = "Marvell Armada XP family SoC";
compatible = "marvell,armadaxp", "marvell,armada-370-xp";
- L2: l2-cache {
- compatible = "marvell,aurora-system-cache";
- reg = <0xd0008000 0x1000>;
- cache-id-part = <0x100>;
- wt-override;
- };
+ soc {
+ internal-regs {
+ L2: l2-cache {
+ compatible = "marvell,aurora-system-cache";
+ reg = <0x08000 0x1000>;
+ cache-id-part = <0x100>;
+ wt-override;
+ };
- mpic: interrupt-controller@d0020000 {
- reg = <0xd0020a00 0x2d0>,
- <0xd0021070 0x58>;
- };
+ mpic: interrupt-controller@20000 {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ };
- armada-370-xp-pmsu@d0022000 {
- compatible = "marvell,armada-370-xp-pmsu";
- reg = <0xd0022100 0x430>,
- <0xd0020800 0x20>;
- };
+ armada-370-xp-pmsu@22000 {
+ compatible = "marvell,armada-370-xp-pmsu";
+ reg = <0x22100 0x430>, <0x20800 0x20>;
+ };
- soc {
- serial@d0012200 {
+ serial@12200 {
compatible = "snps,dw-apb-uart";
- reg = <0xd0012200 0x100>;
+ reg = <0x12200 0x100>;
reg-shift = <2>;
interrupts = <43>;
reg-io-width = <1>;
status = "disabled";
- };
- serial@d0012300 {
+ };
+ serial@12300 {
compatible = "snps,dw-apb-uart";
- reg = <0xd0012300 0x100>;
+ reg = <0x12300 0x100>;
reg-shift = <2>;
interrupts = <44>;
reg-io-width = <1>;
status = "disabled";
- };
+ };
- timer@d0020300 {
+ timer@20300 {
marvell,timer-25Mhz;
- };
+ };
- coreclk: mvebu-sar@d0018230 {
- compatible = "marvell,armada-xp-core-clock";
- reg = <0xd0018230 0x08>;
- #clock-cells = <1>;
- };
+ coreclk: mvebu-sar@18230 {
+ compatible = "marvell,armada-xp-core-clock";
+ reg = <0x18230 0x08>;
+ #clock-cells = <1>;
+ };
- cpuclk: clock-complex@d0018700 {
- #clock-cells = <1>;
- compatible = "marvell,armada-xp-cpu-clock";
- reg = <0xd0018700 0xA0>;
- clocks = <&coreclk 1>;
- };
+ cpuclk: clock-complex@18700 {
+ #clock-cells = <1>;
+ compatible = "marvell,armada-xp-cpu-clock";
+ reg = <0x18700 0xA0>;
+ clocks = <&coreclk 1>;
+ };
- gateclk: clock-gating-control@d0018220 {
- compatible = "marvell,armada-xp-gating-clock";
- reg = <0xd0018220 0x4>;
- clocks = <&coreclk 0>;
- #clock-cells = <1>;
- };
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,armada-xp-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
- system-controller@d0018200 {
+ system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
- reg = <0xd0018200 0x500>;
- };
+ reg = <0x18200 0x500>;
+ };
- ethernet@d0030000 {
+ ethernet@30000 {
compatible = "marvell,armada-370-neta";
- reg = <0xd0030000 0x2500>;
+ reg = <0x30000 0x2500>;
interrupts = <12>;
clocks = <&gateclk 2>;
status = "disabled";
- };
-
- xor@d0060900 {
- compatible = "marvell,orion-xor";
- reg = <0xd0060900 0x100
- 0xd0060b00 0x100>;
- clocks = <&gateclk 22>;
- status = "okay";
-
- xor10 {
- interrupts = <51>;
- dmacap,memcpy;
- dmacap,xor;
- };
- xor11 {
- interrupts = <52>;
- dmacap,memcpy;
- dmacap,xor;
- dmacap,memset;
};
- };
- xor@d00f0900 {
- compatible = "marvell,orion-xor";
- reg = <0xd00F0900 0x100
- 0xd00F0B00 0x100>;
- clocks = <&gateclk 28>;
- status = "okay";
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <51>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <52>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
- xor00 {
- interrupts = <94>;
- dmacap,memcpy;
- dmacap,xor;
+ xor@f0900 {
+ compatible = "marvell,orion-xor";
+ reg = <0xF0900 0x100
+ 0xF0B00 0x100>;
+ clocks = <&gateclk 28>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <94>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <95>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
};
- xor01 {
- interrupts = <95>;
- dmacap,memcpy;
- dmacap,xor;
- dmacap,memset;
+
+ usb@50000 {
+ clocks = <&gateclk 18>;
};
- };
- usb@d0050000 {
- clocks = <&gateclk 18>;
- };
+ usb@51000 {
+ clocks = <&gateclk 19>;
+ };
- usb@d0051000 {
- clocks = <&gateclk 19>;
- };
+ usb@52000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x52000 0x500>;
+ interrupts = <47>;
+ clocks = <&gateclk 20>;
+ status = "disabled";
+ };
- usb@d0052000 {
- compatible = "marvell,orion-ehci";
- reg = <0xd0052000 0x500>;
- interrupts = <47>;
- clocks = <&gateclk 20>;
- status = "disabled";
+ thermal@182b0 {
+ compatible = "marvell,armadaxp-thermal";
+ reg = <0x182b0 0x4
+ 0x184d0 0x4>;
+ status = "okay";
+ };
};
-
};
};
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins>;
+
+ tps: tps@48 {
+ reg = <0x48>;
+ };
};
wdt: wdt@1c21000 {
status = "okay";
};
+ mmc0: mmc@1c40000 {
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ };
+ spi1: spi@1f0e000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins &spi1_cs0_pin>;
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p64";
+ spi-max-frequency = <30000000>;
+ reg = <0>;
+ partition@0 {
+ label = "U-Boot-SPL";
+ reg = <0x00000000 0x00010000>;
+ read-only;
+ };
+ partition@1 {
+ label = "U-Boot";
+ reg = <0x00010000 0x00080000>;
+ read-only;
+ };
+ partition@2 {
+ label = "U-Boot-Env";
+ reg = <0x00090000 0x00010000>;
+ read-only;
+ };
+ partition@3 {
+ label = "Kernel";
+ reg = <0x000a0000 0x00280000>;
+ };
+ partition@4 {
+ label = "Filesystem";
+ reg = <0x00320000 0x00400000>;
+ };
+ partition@5 {
+ label = "MAC-Address";
+ reg = <0x007f0000 0x00010000>;
+ read-only;
+ };
+ };
+ };
};
nand_cs3@62000000 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&nand_cs3_pins>;
};
+ vbat: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+};
+
+/include/ "tps6507x.dtsi"
+
+&tps {
+ vdcdc1_2-supply = <&vbat>;
+ vdcdc3-supply = <&vbat>;
+ vldo1_2-supply = <&vbat>;
+
+ regulators {
+ vdcdc1_reg: regulator@0 {
+ regulator-name = "VDCDC1_3.3V";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdcdc2_reg: regulator@1 {
+ regulator-name = "VDCDC2_3.3V";
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,defdcdc_default = <1>;
+ };
+
+ vdcdc3_reg: regulator@2 {
+ regulator-name = "VDCDC3_1.2V";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,defdcdc_default = <1>;
+ };
+
+ ldo1_reg: regulator@3 {
+ regulator-name = "LDO1_1.8V";
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <1890000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-name = "LDO2_1.2V";
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
};
0x10 0x00002200 0x0000ff00
>;
};
+ mmc0_pins: pinmux_mmc_pins {
+ pinctrl-single,bits = <
+ /* MMCSD0_DAT[3] MMCSD0_DAT[2]
+ * MMCSD0_DAT[1] MMCSD0_DAT[0]
+ * MMCSD0_CMD MMCSD0_CLK
+ */
+ 0x28 0x00222222 0x00ffffff
+ >;
+ };
+ ehrpwm0a_pins: pinmux_ehrpwm0a_pins {
+ pinctrl-single,bits = <
+ /* EPWM0A */
+ 0xc 0x00000002 0x0000000f
+ >;
+ };
+ ehrpwm0b_pins: pinmux_ehrpwm0b_pins {
+ pinctrl-single,bits = <
+ /* EPWM0B */
+ 0xc 0x00000020 0x000000f0
+ >;
+ };
+ ehrpwm1a_pins: pinmux_ehrpwm1a_pins {
+ pinctrl-single,bits = <
+ /* EPWM1A */
+ 0x14 0x00000002 0x0000000f
+ >;
+ };
+ ehrpwm1b_pins: pinmux_ehrpwm1b_pins {
+ pinctrl-single,bits = <
+ /* EPWM1B */
+ 0x14 0x00000020 0x000000f0
+ >;
+ };
+ ecap0_pins: pinmux_ecap0_pins {
+ pinctrl-single,bits = <
+ /* ECAP0_APWM0 */
+ 0x8 0x20000000 0xf0000000
+ >;
+ };
+ ecap1_pins: pinmux_ecap1_pins {
+ pinctrl-single,bits = <
+ /* ECAP1_APWM1 */
+ 0x4 0x40000000 0xf0000000
+ >;
+ };
+ ecap2_pins: pinmux_ecap2_pins {
+ pinctrl-single,bits = <
+ /* ECAP2_APWM2 */
+ 0x4 0x00000004 0x0000000f
+ >;
+ };
+ spi1_pins: pinmux_spi_pins {
+ pinctrl-single,bits = <
+ /* SIMO, SOMI, CLK */
+ 0x14 0x00110100 0x00ff0f00
+ >;
+ };
+ spi1_cs0_pin: pinmux_spi1_cs0 {
+ pinctrl-single,bits = <
+ /* CS0 */
+ 0x14 0x00000010 0x000000f0
+ >;
+ };
};
serial0: serial@1c42000 {
compatible = "ns16550a";
reg = <0x21000 0x1000>;
status = "disabled";
};
+ mmc0: mmc@1c40000 {
+ compatible = "ti,da830-mmc";
+ reg = <0x40000 0x1000>;
+ interrupts = <16>;
+ status = "disabled";
+ };
+ ehrpwm0: ehrpwm@01f00000 {
+ compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x300000 0x2000>;
+ status = "disabled";
+ };
+ ehrpwm1: ehrpwm@01f02000 {
+ compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x302000 0x2000>;
+ status = "disabled";
+ };
+ ecap0: ecap@01f06000 {
+ compatible = "ti,da850-ecap", "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x306000 0x80>;
+ status = "disabled";
+ };
+ ecap1: ecap@01f07000 {
+ compatible = "ti,da850-ecap", "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x307000 0x80>;
+ status = "disabled";
+ };
+ ecap2: ecap@01f08000 {
+ compatible = "ti,da850-ecap", "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x308000 0x80>;
+ status = "disabled";
+ };
+ spi1: spi@1f0e000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,da830-spi";
+ reg = <0x30e000 0x1000>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <1>;
+ interrupts = <56>;
+ status = "disabled";
+ };
};
nand_cs3@62000000 {
compatible = "ti,davinci-nand";
#clock-cells = <1>;
};
+ thermal: thermal@d001c {
+ compatible = "marvell,dove-thermal";
+ reg = <0xd001c 0x0c>, <0xd005c 0x08>;
+ };
+
uart0: serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
<0x7 0 &gic 1 12 0>;
};
};
+
+ mshc@12550000 {
+ compatible = "samsung,exynos4412-dw-mshc";
+ reg = <0x12550000 0x1000>;
+ interrupts = <0 77 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a>;
- panel-enable-gpios = <&gpio1 18 0>;
+ lcd-supply = <®_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>;
+ };
+ };
+ };
};
};
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 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
bus-width = <4>;
+ broken-cd;
status = "okay";
};
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>;
};
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";
};
reg = <0x80010000 0x2000>;
interrupts = <15 14>;
clocks = <&clks 33>;
+ dmas = <&dma_apbh 1>;
+ dma-names = "rx-tx";
fsl,ssp-dma-channel = <1>;
status = "disabled";
};
};
digctl@8001c000 {
+ compatible = "fsl,imx23-digctl";
reg = <0x8001c000 2000>;
status = "disabled";
};
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>;
};
};
ocotp@8002c000 {
+ compatible = "fsl,ocotp";
reg = <0x8002c000 0x2000>;
status = "disabled";
};
reg = <0x80034000 0x2000>;
interrupts = <2 20>;
clocks = <&clks 33>;
+ dmas = <&dma_apbh 2>;
+ dma-names = "rx-tx";
fsl,ssp-dma-channel = <2>;
status = "disabled";
};
ranges;
clks: clkctrl@80040000 {
- compatible = "fsl,imx23-clkctrl";
+ compatible = "fsl,imx23-clkctrl", "fsl,clkctrl";
reg = <0x80040000 0x2000>;
#clock-cells = <1>;
};
saif0: saif@80042000 {
reg = <0x80042000 0x2000>;
+ dmas = <&dma_apbx 4>;
+ dma-names = "rx-tx";
status = "disabled";
};
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";
};
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";
};
compatible = "fsl,imx23-timrot", "fsl,timrot";
reg = <0x80068000 0x2000>;
interrupts = <28 29 30 31>;
+ clocks = <&clks 28>;
};
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";
};
reg = <0x8006e000 0x2000>;
interrupts = <59 60 58>;
clocks = <&clks 32>;
+ dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+ dma-names = "rx", "tx";
status = "disabled";
};
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>;
+ };
+ };
+ };
};
};
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>;
+ };
+ };
+ };
};
};
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 */
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>;
+ };
+ };
+ };
};
};
usbphy1: usbphy@8007e000 {
status = "okay";
};
+
+ lradc@80050000 {
+ status = "okay";
+ fsl,lradc-touchscreen-wires = <4>;
+ };
};
};
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>;
};
};
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a
&lcdif_pins_evk>;
- panel-enable-gpios = <&gpio3 30 0>;
+ lcd-supply = <®_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 {
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 {
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 {
phy-mode = "rmii";
pinctrl-names = "default";
pinctrl-0 = <&mac0_pins_a>;
+ clocks = <&clks 57>, <&clks 57>;
+ clock-names = "ipg", "ahb";
status = "okay";
};
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>;
};
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";
};
reg = <0x80010000 0x2000>;
interrupts = <96 82>;
clocks = <&clks 46>;
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
fsl,ssp-dma-channel = <0>;
status = "disabled";
};
reg = <0x80012000 0x2000>;
interrupts = <97 83>;
clocks = <&clks 47>;
+ dmas = <&dma_apbh 1>;
+ dma-names = "rx-tx";
fsl,ssp-dma-channel = <1>;
status = "disabled";
};
reg = <0x80014000 0x2000>;
interrupts = <98 84>;
clocks = <&clks 48>;
+ dmas = <&dma_apbh 2>;
+ dma-names = "rx-tx";
fsl,ssp-dma-channel = <2>;
status = "disabled";
};
reg = <0x80016000 0x2000>;
interrupts = <99 85>;
clocks = <&clks 49>;
+ dmas = <&dma_apbh 3>;
+ dma-names = "rx-tx";
fsl,ssp-dma-channel = <3>;
status = "disabled";
};
};
digctl@8001c000 {
+ compatible = "fsl,imx28-digctl";
reg = <0x8001c000 0x2000>;
interrupts = <89>;
status = "disabled";
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>;
};
};
ocotp@8002c000 {
+ compatible = "fsl,ocotp";
reg = <0x8002c000 0x2000>;
status = "disabled";
};
reg = <0x80030000 0x2000>;
interrupts = <38 86>;
clocks = <&clks 55>;
+ dmas = <&dma_apbh 13>;
+ dma-names = "rx";
status = "disabled";
};
ranges;
clks: clkctrl@80040000 {
- compatible = "fsl,imx28-clkctrl";
+ compatible = "fsl,imx28-clkctrl", "fsl,clkctrl";
reg = <0x80040000 0x2000>;
#clock-cells = <1>;
};
reg = <0x80042000 0x2000>;
interrupts = <59 80>;
clocks = <&clks 53>;
+ dmas = <&dma_apbx 4>;
+ dma-names = "rx-tx";
fsl,saif-dma-channel = <4>;
status = "disabled";
};
reg = <0x80046000 0x2000>;
interrupts = <58 81>;
clocks = <&clks 54>;
+ dmas = <&dma_apbx 5>;
+ dma-names = "rx-tx";
fsl,saif-dma-channel = <5>;
status = "disabled";
};
spdif@80054000 {
reg = <0x80054000 0x2000>;
interrupts = <45 66>;
+ dmas = <&dma_apbx 2>;
+ dma-names = "tx";
status = "disabled";
};
reg = <0x80058000 0x2000>;
interrupts = <111 68>;
clock-frequency = <100000>;
+ dmas = <&dma_apbx 6>;
+ dma-names = "rx-tx";
fsl,i2c-dma-channel = <6>;
status = "disabled";
};
reg = <0x8005a000 0x2000>;
interrupts = <110 69>;
clock-frequency = <100000>;
+ dmas = <&dma_apbx 7>;
+ dma-names = "rx-tx";
fsl,i2c-dma-channel = <7>;
status = "disabled";
};
compatible = "fsl,imx28-timrot", "fsl,timrot";
reg = <0x80068000 0x2000>;
interrupts = <48 49 50 51>;
+ clocks = <&clks 26>;
};
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";
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";
};
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";
};
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";
};
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";
};
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";
};
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>;
};
<&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";
};
};
};
+ thermal@10078 {
+ compatible = "marvell,kirkwood-thermal";
+ reg = <0x10078 0x4>;
+ status = "okay";
+ };
+
i2c@11100 {
compatible = "marvell,mv64xxx-i2c";
reg = <0x11100 0x20>;
status = "okay";
nr-ports = <1>;
};
+
+ mvsdio@90000 {
+ status = "okay";
+ };
};
gpio-leds {
};
};
+ pmu {
+ compatible = "arm,arm1136-pmu";
+ interrupts = <3>;
+ };
+
soc {
compatible = "ti,omap-infra";
mpu {
reg = <0x480FE000 0x1000>;
};
+ sdma: dma-controller@48056000 {
+ compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
+ reg = <0x48056000 0x1000>;
+ interrupts = <12>,
+ <13>,
+ <14>,
+ <15>;
+ #dma-cells = <1>;
+ #dma-channels = <32>;
+ #dma-requests = <64>;
+ };
+
uart1: serial@4806a000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart1";
};
timer2: timer@4802a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x4802a000 0x400>;
interrupts = <38>;
ti,hwmods = "timer2";
};
timer3: timer@48078000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48078000 0x400>;
interrupts = <39>;
ti,hwmods = "timer3";
};
timer4: timer@4807a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x4807a000 0x400>;
interrupts = <40>;
ti,hwmods = "timer4";
};
timer5: timer@4807c000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x4807c000 0x400>;
interrupts = <41>;
ti,hwmods = "timer5";
};
timer6: timer@4807e000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x4807e000 0x400>;
interrupts = <42>;
ti,hwmods = "timer6";
};
timer7: timer@48080000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48080000 0x400>;
interrupts = <43>;
ti,hwmods = "timer7";
};
timer8: timer@48082000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48082000 0x400>;
interrupts = <44>;
ti,hwmods = "timer8";
};
timer9: timer@48084000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48084000 0x400>;
interrupts = <45>;
ti,hwmods = "timer9";
};
timer10: timer@48086000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48086000 0x400>;
interrupts = <46>;
ti,hwmods = "timer10";
};
timer11: timer@48088000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48088000 0x400>;
interrupts = <47>;
ti,hwmods = "timer11";
};
timer12: timer@4808a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x4808a000 0x400>;
interrupts = <48>;
ti,hwmods = "timer12";
reg = <0x80000000 0x4000000>; /* 64 MB */
};
};
+
+&gpmc {
+ ranges = <0 0 0x08000000 0x04000000>;
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ linux,mtd-name= "intel,ge28f256l18b85";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x04000000>;
+ bank-width = <2>;
+
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <10>;
+ gpmc,cs-rd-off-ns = <160>;
+ gpmc,cs-wr-off-ns = <160>;
+ gpmc,adv-on-ns = <20>;
+ gpmc,adv-rd-off-ns = <50>;
+ gpmc,adv-wr-off-ns = <50>;
+ gpmc,oe-on-ns = <60>;
+ gpmc,oe-off-ns = <120>;
+ gpmc,we-on-ns = <60>;
+ gpmc,we-off-ns = <120>;
+ gpmc,rd-cycle-ns = <170>;
+ gpmc,wr-cycle-ns = <170>;
+ gpmc,access-ns = <150>;
+ gpmc,page-burst-access-ns = <10>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0 0x20000>;
+ };
+ partition@0x20000 {
+ label = "params";
+ reg = <0x20000 0x20000>;
+ };
+ partition@0x40000 {
+ label = "kernel";
+ reg = <0x40000 0x200000>;
+ };
+ partition@0x240000 {
+ label = "file-system";
+ reg = <0x240000 0x3dc0000>;
+ };
+ };
+};
pinctrl-single,function-mask = <0x3f>;
};
+ gpio1: gpio@48018000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x48018000 0x200>;
+ interrupts = <29>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@4801a000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4801a000 0x200>;
+ interrupts = <30>;
+ ti,hwmods = "gpio2";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@4801c000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4801c000 0x200>;
+ interrupts = <31>;
+ ti,hwmods = "gpio3";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@4801e000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4801e000 0x200>;
+ interrupts = <32>;
+ ti,hwmods = "gpio4";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpmc: gpmc@6800a000 {
+ compatible = "ti,omap2420-gpmc";
+ reg = <0x6800a000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <20>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
+ };
+
mcbsp1: mcbsp@48074000 {
compatible = "ti,omap2420-mcbsp";
reg = <0x48074000 0xff>;
<60>; /* RX interrupt */
interrupt-names = "tx", "rx";
ti,hwmods = "mcbsp1";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
};
mcbsp2: mcbsp@48076000 {
<63>; /* RX interrupt */
interrupt-names = "tx", "rx";
ti,hwmods = "mcbsp2";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
};
timer1: timer@48028000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x48028000 0x400>;
interrupts = <37>;
ti,hwmods = "timer1";
pinctrl-single,function-mask = <0x3f>;
};
+ gpio1: gpio@4900c000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4900c000 0x200>;
+ interrupts = <29>;
+ ti,hwmods = "gpio1";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@4900e000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x4900e000 0x200>;
+ interrupts = <30>;
+ ti,hwmods = "gpio2";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio3: gpio@49010000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x49010000 0x200>;
+ interrupts = <31>;
+ ti,hwmods = "gpio3";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio4: gpio@49012000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x49012000 0x200>;
+ interrupts = <32>;
+ ti,hwmods = "gpio4";
+ ti,gpio-always-on;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpio5: gpio@480b6000 {
+ compatible = "ti,omap2-gpio";
+ reg = <0x480b6000 0x200>;
+ interrupts = <33>;
+ ti,hwmods = "gpio5";
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ gpmc: gpmc@6e000000 {
+ compatible = "ti,omap2430-gpmc";
+ reg = <0x6e000000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <20>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
+ };
+
mcbsp1: mcbsp@48074000 {
compatible = "ti,omap2430-mcbsp";
reg = <0x48074000 0xff>;
interrupt-names = "common", "tx", "rx", "rx_overflow";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp1";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
};
mcbsp2: mcbsp@48076000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp2";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
};
mcbsp3: mcbsp@4808c000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp3";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
};
mcbsp4: mcbsp@4808e000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp4";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
};
mcbsp5: mcbsp@48096000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp5";
+ dmas = <&sdma 21>,
+ <&sdma 22>;
+ dma-names = "tx", "rx";
};
timer1: timer@49018000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap2420-timer";
reg = <0x49018000 0x400>;
interrupts = <37>;
ti,hwmods = "timer1";
model = "TI OMAP3 BeagleBoard xM";
compatible = "ti,omap3-beagle-xm, ti,omap3-beagle", "ti,omap3";
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>; /* 512 MB */
leds {
compatible = "gpio-leds";
- pmu_stat {
- label = "beagleboard::pmu_stat";
- gpios = <&twl_gpio 19 0>; /* LEDB */
- };
heartbeat {
label = "beagleboard::usr0";
};
};
+ pwmleds {
+ compatible = "pwm-leds";
+
+ pmu_stat {
+ label = "beagleboard::pmu_stat";
+ pwms = <&twl_pwmled 1 7812500>;
+ max-brightness = <127>;
+ };
+ };
+
sound {
compatible = "ti,omap-twl4030";
ti,model = "omap3beagle";
*/
ti,pulldowns = <0x03a1c4>;
};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ mode = <3>;
+ power = <50>;
+};
*/
/dts-v1/;
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
/ {
model = "TI OMAP3 BeagleBoard";
compatible = "ti,omap3-beagle", "ti,omap3";
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
memory {
device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256 MB */
};
};
+ /* HS USB Port 2 RESET */
+ hsusb2_reset: hsusb2_reset_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_reset";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 19 0>; /* gpio_147 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ /* HS USB Port 2 Power */
+ hsusb2_power: hsusb2_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb2_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 2 */
+ hsusb2_phy: hsusb2_phy {
+ compatible = "usb-nop-xceiv";
+ reset-supply = <&hsusb2_reset>;
+ vcc-supply = <&hsusb2_power>;
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb2_pins
+ >;
+
+ hsusbb2_pins: pinmux_hsusbb2_pins {
+ pinctrl-single,pins = <
+ 0x5c0 0x3 /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_clk OUTPUT */
+ 0x5c2 0x3 /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_stp OUTPUT */
+ 0x5c4 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dir INPUT | PULLDOWN */
+ 0x5c6 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_nxt INPUT | PULLDOWN */
+ 0x5c8 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat0 INPUT | PULLDOWN */
+ 0x5cA 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat1 INPUT | PULLDOWN */
+ 0x1a4 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat2 INPUT | PULLDOWN */
+ 0x1a6 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat3 INPUT | PULLDOWN */
+ 0x1a8 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat4 INPUT | PULLDOWN */
+ 0x1aa 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat5 INPUT | PULLDOWN */
+ 0x1ac 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat6 INPUT | PULLDOWN */
+ 0x1ae 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat7 INPUT | PULLDOWN */
+ >;
+ };
};
&i2c1 {
&mmc3 {
status = "disabled";
};
+
+&usbhshost {
+ port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <0 &hsusb2_phy>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+ /* pullups: BIT(1) */
+ ti,pullups = <0x000002>;
+ /*
+ * pulldowns:
+ * BIT(2), BIT(6), BIT(7), BIT(8), BIT(13)
+ * BIT(15), BIT(16), BIT(17)
+ */
+ ti,pulldowns = <0x03a1c4>;
+};
--- /dev/null
+/*
+ * Author: Anil Kumar <anilk4.v@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "omap34xx.dtsi"
+/ {
+ model = "TimLL OMAP3 Devkit8000";
+ compatible = "timll,omap3-devkit8000", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ heartbeat {
+ label = "devkit8000::led1";
+ gpios = <&gpio6 26 0>; /* 186 -> LED1 */
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ mmc {
+ label = "devkit8000::led2";
+ gpios = <&gpio6 3 0>; /* 163 -> LED2 */
+ default-state = "on";
+ linux,default-trigger = "none";
+ };
+
+ usr {
+ label = "devkit8000::led3";
+ gpios = <&gpio6 4 0>; /* 164 -> LED3 */
+ default-state = "on";
+ linux,default-trigger = "usr";
+ };
+
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "devkit8000";
+
+ ti,mcbsp = <&mcbsp2>;
+ ti,codec = <&twl_audio>;
+ ti,audio-routing =
+ "Ext Spk", "PREDRIVEL",
+ "Ext Spk", "PREDRIVER",
+ "MAINMIC", "Main Mic",
+ "Main Mic", "Mic Bias 1";
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+/include/ "twl4030.dtsi"
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&wdt2 {
+ status = "disabled";
+};
+
+&mcbsp1 {
+ status = "disabled";
+};
+
+&mcbsp3 {
+ status = "disabled";
+};
+
+&mcbsp4 {
+ status = "disabled";
+};
+
+&mcbsp5 {
+ status = "disabled";
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x04>; /* CS0: NAND */
+
+ nand@0,0 {
+ reg = <0 0 0>; /* CS0, offset 0 */
+ nand-bus-width = <16>;
+
+ gpmc,sync-clk = <0>;
+ gpmc,cs-on = <0>;
+ gpmc,cs-rd-off = <44>;
+ gpmc,cs-wr-off = <44>;
+ gpmc,adv-on = <6>;
+ gpmc,adv-rd-off = <34>;
+ gpmc,adv-wr-off = <44>;
+ gpmc,we-off = <40>;
+ gpmc,oe-off = <54>;
+ gpmc,access = <64>;
+ gpmc,rd-cycle = <82>;
+ gpmc,wr-cycle = <82>;
+ gpmc,wr-access = <40>;
+ gpmc,wr-data-mux-bus = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ x-loader@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+
+ bootloaders@80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1e0000>;
+ };
+
+ bootloaders_env@260000 {
+ label = "U-Boot Env";
+ reg = <0x260000 0x20000>;
+ };
+
+ kernel@280000 {
+ label = "Kernel";
+ reg = <0x280000 0x400000>;
+ };
+
+ filesystem@680000 {
+ label = "File System";
+ reg = <0x680000 0xf980000>;
+ };
+ };
+};
*/
/dts-v1/;
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
/ {
model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)";
compatible = "ti,omap3-evm", "ti,omap3";
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vcc>;
+ };
+ };
+
memory {
device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256 MB */
&twl_gpio {
ti,use-leds;
};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ mode = <3>;
+ power = <50>;
+};
--- /dev/null
+/*
+ * Device Tree Source for IGEP Technology devices
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "omap34xx.dtsi"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "igep2";
+ ti,mcbsp = <&mcbsp2>;
+ ti,codec = <&twl_audio>;
+ };
+};
+
+&omap3_pmx_core {
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x152 0x100 /* uart1_rx.uart1_rx INPUT | MODE0 */
+ 0x14c 0 /* uart1_tx.uart1_tx OUTPUT | MODE0 */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ 0x14a 0x100 /* uart2_rx.uart2_rx INPUT | MODE0 */
+ 0x148 0 /* uart2_tx.uart2_tx OUTPUT | MODE0 */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ 0x16e 0x100 /* uart3_rx.uart3_rx INPUT | MODE0 */
+ 0x170 0 /* uart3_tx.uart3_tx OUTPUT | MODE0 */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ 0x114 0x0118 /* sdmmc1_clk.sdmmc1_clk INPUT PULLUP | MODE 0 */
+ 0x116 0x0118 /* sdmmc1_cmd.sdmmc1_cmd INPUT PULLUP | MODE 0 */
+ 0x118 0x0118 /* sdmmc1_dat0.sdmmc1_dat0 INPUT PULLUP | MODE 0 */
+ 0x11a 0x0118 /* sdmmc1_dat1.sdmmc1_dat1 INPUT PULLUP | MODE 0 */
+ 0x11c 0x0118 /* sdmmc1_dat2.sdmmc1_dat2 INPUT PULLUP | MODE 0 */
+ 0x11e 0x0118 /* sdmmc1_dat3.sdmmc1_dat3 INPUT PULLUP | MODE 0 */
+ 0x120 0x0100 /* sdmmc1_dat4.sdmmc1_dat4 INPUT | MODE 0 */
+ 0x122 0x0100 /* sdmmc1_dat5.sdmmc1_dat5 INPUT | MODE 0 */
+ 0x124 0x0100 /* sdmmc1_dat6.sdmmc1_dat6 INPUT | MODE 0 */
+ 0x126 0x0100 /* sdmmc1_dat7.sdmmc1_dat7 INPUT | MODE 0 */
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+/include/ "twl4030.dtsi"
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
--- /dev/null
+/*
+ * Device Tree Source for IGEPv2 board
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "omap3-igep.dtsi"
+
+/ {
+ model = "IGEPv2";
+ compatible = "isee,omap3-igep0020", "ti,omap3";
+
+ leds {
+ compatible = "gpio-leds";
+ boot {
+ label = "omap3:green:boot";
+ gpios = <&gpio1 26 0>;
+ default-state = "on";
+ };
+
+ user0 {
+ label = "omap3:red:user0";
+ gpios = <&gpio1 27 0>;
+ default-state = "off";
+ };
+
+ user1 {
+ label = "omap3:red:user1";
+ gpios = <&gpio1 28 0>;
+ default-state = "off";
+ };
+
+ user2 {
+ label = "omap3:green:user1";
+ gpios = <&twl_gpio 19 1>;
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ /*
+ * Display monitor features are burnt in the EEPROM
+ * as EDID data.
+ */
+ eeprom@50 {
+ compatible = "ti,eeprom";
+ reg = <0x50>;
+ };
+};
--- /dev/null
+/*
+ * Device Tree Source for IGEP COM Module
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "omap3-igep.dtsi"
+
+/ {
+ model = "IGEP COM Module";
+ compatible = "isee,omap3-igep0030", "ti,omap3";
+
+ leds {
+ compatible = "gpio-leds";
+ boot {
+ label = "omap3:green:boot";
+ gpios = <&twl_gpio 13 1>;
+ default-state = "on";
+ };
+
+ user0 {
+ label = "omap3:red:user0";
+ gpios = <&twl_gpio 18 1>; /* LEDA */
+ default-state = "off";
+ };
+
+ user1 {
+ label = "omap3:green:user1";
+ gpios = <&twl_gpio 19 1>; /* LEDB */
+ default-state = "off";
+ };
+
+ user2 {
+ label = "omap3:red:user1";
+ gpios = <&gpio1 16 1>;
+ default-state = "off";
+ };
+ };
+};
*/
/dts-v1/;
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
/ {
- leds {
- compatible = "gpio-leds";
+ pwmleds {
+ compatible = "pwm-leds";
+
overo {
label = "overo:blue:COM";
- gpios = <&twl_gpio 19 0>;
- linux,default-trigger = "mmc0";
+ pwms = <&twl_pwmled 1 7812500>;
+ max-brightness = <127>;
};
};
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "overo";
+
+ ti,mcbsp = <&mcbsp2>;
+ ti,codec = <&twl_audio>;
+ };
};
&i2c1 {
reg = <0x48>;
interrupts = <7>; /* SYS_NIRQ cascaded to intc */
interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
};
};
&twl_gpio {
ti,use-leds;
};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ mode = <3>;
+ power = <50>;
+};
};
};
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ interrupts = <3>;
+ ti,hwmods = "debugss";
+ };
+
/*
- * The soc node represents the soc top level view. It is uses for IPs
+ * The soc node represents the soc top level view. It is used for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
*/
soc {
reg = <0x48200000 0x1000>;
};
+ sdma: dma-controller@48056000 {
+ compatible = "ti,omap3630-sdma", "ti,omap3430-sdma";
+ reg = <0x48056000 0x1000>;
+ interrupts = <12>,
+ <13>,
+ <14>,
+ <15>;
+ #dma-cells = <1>;
+ #dma-channels = <32>;
+ #dma-requests = <96>;
+ };
+
omap3_pmx_core: pinmux@48002030 {
compatible = "ti,omap3-padconf", "pinctrl-single";
reg = <0x48002030 0x05cc>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-single,register-width = <16>;
- pinctrl-single,function-mask = <0x7fff>;
+ pinctrl-single,function-mask = <0x7f1f>;
};
- omap3_pmx_wkup: pinmux@0x48002a58 {
+ omap3_pmx_wkup: pinmux@0x48002a00 {
compatible = "ti,omap3-padconf", "pinctrl-single";
- reg = <0x48002a58 0x5c>;
+ reg = <0x48002a00 0x5c>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-single,register-width = <16>;
- pinctrl-single,function-mask = <0x7fff>;
+ pinctrl-single,function-mask = <0x7f1f>;
};
gpio1: gpio@48310000 {
compatible = "ti,omap3-gpio";
+ reg = <0x48310000 0x200>;
+ interrupts = <29>;
ti,hwmods = "gpio1";
+ ti,gpio-always-on;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio2: gpio@49050000 {
compatible = "ti,omap3-gpio";
+ reg = <0x49050000 0x200>;
+ interrupts = <30>;
ti,hwmods = "gpio2";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio3: gpio@49052000 {
compatible = "ti,omap3-gpio";
+ reg = <0x49052000 0x200>;
+ interrupts = <31>;
ti,hwmods = "gpio3";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio4: gpio@49054000 {
compatible = "ti,omap3-gpio";
+ reg = <0x49054000 0x200>;
+ interrupts = <32>;
ti,hwmods = "gpio4";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio5: gpio@49056000 {
compatible = "ti,omap3-gpio";
+ reg = <0x49056000 0x200>;
+ interrupts = <33>;
ti,hwmods = "gpio5";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio6: gpio@49058000 {
compatible = "ti,omap3-gpio";
+ reg = <0x49058000 0x200>;
+ interrupts = <34>;
ti,hwmods = "gpio6";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
uart1: serial@4806a000 {
#size-cells = <0>;
ti,hwmods = "mcspi1";
ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
};
mcspi2: spi@4809a000 {
#size-cells = <0>;
ti,hwmods = "mcspi2";
ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
};
mcspi3: spi@480b8000 {
#size-cells = <0>;
ti,hwmods = "mcspi3";
ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>,
+ <&sdma 16>,
+ <&sdma 23>,
+ <&sdma 24>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
};
mcspi4: spi@480ba000 {
#size-cells = <0>;
ti,hwmods = "mcspi4";
ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
};
mmc1: mmc@4809c000 {
compatible = "ti,omap3-hsmmc";
ti,hwmods = "mmc1";
ti,dual-volt;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
};
mmc2: mmc@480b4000 {
compatible = "ti,omap3-hsmmc";
ti,hwmods = "mmc2";
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
};
mmc3: mmc@480ad000 {
compatible = "ti,omap3-hsmmc";
ti,hwmods = "mmc3";
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
};
wdt2: wdt@48314000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp1";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
};
mcbsp2: mcbsp@49022000 {
interrupt-names = "common", "tx", "rx", "sidetone";
ti,buffer-size = <1280>;
ti,hwmods = "mcbsp2", "mcbsp2_sidetone";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
};
mcbsp3: mcbsp@49024000 {
interrupt-names = "common", "tx", "rx", "sidetone";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp3", "mcbsp3_sidetone";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
};
mcbsp4: mcbsp@49026000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp4";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
};
mcbsp5: mcbsp@48096000 {
interrupt-names = "common", "tx", "rx";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp5";
+ dmas = <&sdma 21>,
+ <&sdma 22>;
+ dma-names = "tx", "rx";
};
timer1: timer@48318000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48318000 0x400>;
interrupts = <37>;
ti,hwmods = "timer1";
};
timer2: timer@49032000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x49032000 0x400>;
interrupts = <38>;
ti,hwmods = "timer2";
};
timer3: timer@49034000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x49034000 0x400>;
interrupts = <39>;
ti,hwmods = "timer3";
};
timer4: timer@49036000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x49036000 0x400>;
interrupts = <40>;
ti,hwmods = "timer4";
};
timer5: timer@49038000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x49038000 0x400>;
interrupts = <41>;
ti,hwmods = "timer5";
};
timer6: timer@4903a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x4903a000 0x400>;
interrupts = <42>;
ti,hwmods = "timer6";
};
timer7: timer@4903c000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x4903c000 0x400>;
interrupts = <43>;
ti,hwmods = "timer7";
};
timer8: timer@4903e000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x4903e000 0x400>;
interrupts = <44>;
ti,hwmods = "timer8";
};
timer9: timer@49040000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x49040000 0x400>;
interrupts = <45>;
ti,hwmods = "timer9";
};
timer10: timer@48086000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48086000 0x400>;
interrupts = <46>;
ti,hwmods = "timer10";
};
timer11: timer@48088000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48088000 0x400>;
interrupts = <47>;
ti,hwmods = "timer11";
};
timer12: timer@48304000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48304000 0x400>;
interrupts = <95>;
ti,hwmods = "timer12";
ti,timer-alwon;
ti,timer-secure;
};
+
+ usbhstll: usbhstll@48062000 {
+ compatible = "ti,usbhs-tll";
+ reg = <0x48062000 0x1000>;
+ interrupts = <78>;
+ ti,hwmods = "usb_tll_hs";
+ };
+
+ usbhshost: usbhshost@48064000 {
+ compatible = "ti,usbhs-host";
+ reg = <0x48064000 0x400>;
+ ti,hwmods = "usb_host_hs";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usbhsohci: ohci@48064400 {
+ compatible = "ti,ohci-omap3", "usb-ohci";
+ reg = <0x48064400 0x400>;
+ interrupt-parent = <&intc>;
+ interrupts = <76>;
+ };
+
+ usbhsehci: ehci@48064800 {
+ compatible = "ti,ehci-omap", "usb-ehci";
+ reg = <0x48064800 0x400>;
+ interrupt-parent = <&intc>;
+ interrupts = <77>;
+ };
+ };
+
+ gpmc: gpmc@6e000000 {
+ compatible = "ti,omap3430-gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x6e000000 0x02d0>;
+ interrupts = <20>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ usb_otg_hs: usb_otg_hs@480ab000 {
+ compatible = "ti,omap3-musb";
+ reg = <0x480ab000 0x1000>;
+ interrupts = <0 92 0x4>, <0 93 0x4>;
+ interrupt-names = "mc", "dma";
+ ti,hwmods = "usb_otg_hs";
+ usb-phy = <&usb2_phy>;
+ multipoint = <1>;
+ num-eps = <16>;
+ ram-bits = <12>;
+ };
};
};
--- /dev/null
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "omap34xx.dtsi"
+
+/ {
+ model = "TI OMAP3430 SDP";
+ compatible = "ti,omap3430-sdp", "ti,omap3";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+};
+
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ };
+};
+
+/include/ "twl4030.dtsi"
+
+&mmc1 {
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&gpmc {
+ ranges = <0 0 0x10000000 0x08000000>,
+ <1 0 0x28000000 0x08000000>,
+ <2 0 0x20000000 0x10000000>;
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ linux,mtd-name= "intel,pf48f6000m0y1be";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <186>;
+ gpmc,cs-wr-off-ns = <186>;
+ gpmc,adv-on-ns = <12>;
+ gpmc,adv-rd-off-ns = <48>;
+ gpmc,adv-wr-off-ns = <48>;
+ gpmc,oe-on-ns = <54>;
+ gpmc,oe-off-ns = <168>;
+ gpmc,we-on-ns = <54>;
+ gpmc,we-off-ns = <168>;
+ gpmc,rd-cycle-ns = <186>;
+ gpmc,wr-cycle-ns = <186>;
+ gpmc,access-ns = <114>;
+ gpmc,page-burst-access-ns = <6>;
+ gpmc,bus-turnaround-ns = <12>;
+ gpmc,cycle2cycle-delay-ns = <18>;
+ gpmc,wr-data-mux-bus-ns = <90>;
+ gpmc,wr-access-ns = <186>;
+ gpmc,cycle2cycle-samecsen;
+ gpmc,cycle2cycle-diffcsen;
+
+ partition@0 {
+ label = "bootloader-nor";
+ reg = <0 0x40000>;
+ };
+ partition@0x40000 {
+ label = "params-nor";
+ reg = <0x40000 0x40000>;
+ };
+ partition@0x80000 {
+ label = "kernel-nor";
+ reg = <0x80000 0x200000>;
+ };
+ partition@0x280000 {
+ label = "filesystem-nor";
+ reg = <0x240000 0x7d80000>;
+ };
+ };
+
+ nand@1,0 {
+ linux,mtd-name= "micron,mt29f1g08abb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <1 0 0x08000000>;
+ nand-bus-width = <8>;
+
+ ti,nand-ecc-opt = "sw";
+ gpmc,device-nand;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <36>;
+ gpmc,cs-wr-off-ns = <36>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <24>;
+ gpmc,adv-wr-off-ns = <36>;
+ gpmc,oe-on-ns = <6>;
+ gpmc,oe-off-ns = <48>;
+ gpmc,we-on-ns = <6>;
+ gpmc,we-off-ns = <30>;
+ gpmc,rd-cycle-ns = <72>;
+ gpmc,wr-cycle-ns = <72>;
+ gpmc,access-ns = <54>;
+ gpmc,wr-access-ns = <30>;
+
+ partition@0 {
+ label = "xloader-nand";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "bootloader-nand";
+ reg = <0x80000 0x140000>;
+ };
+ partition@0x1c0000 {
+ label = "params-nand";
+ reg = <0x1c0000 0xc0000>;
+ };
+ partition@0x280000 {
+ label = "kernel-nand";
+ reg = <0x280000 0x500000>;
+ };
+ partition@0x780000 {
+ label = "filesystem-nand";
+ reg = <0x780000 0x7880000>;
+ };
+ };
+
+ onenand@2,0 {
+ linux,mtd-name= "samsung,kfm2g16q2m-deb8";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <2 0 0x10000000>;
+
+ gpmc,device-width = <2>;
+ gpmc,mux-add-data = <2>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <84>;
+ gpmc,cs-wr-off-ns = <72>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <18>;
+ gpmc,adv-wr-off-ns = <18>;
+ gpmc,oe-on-ns = <30>;
+ gpmc,oe-off-ns = <84>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <42>;
+ gpmc,rd-cycle-ns = <108>;
+ gpmc,wr-cycle-ns = <96>;
+ gpmc,access-ns = <78>;
+ gpmc,wr-data-mux-bus-ns = <30>;
+
+ partition@0 {
+ label = "xloader-onenand";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "bootloader-onenand";
+ reg = <0x80000 0x40000>;
+ };
+ partition@0xc0000 {
+ label = "params-onenand";
+ reg = <0xc0000 0x20000>;
+ };
+ partition@0xe0000 {
+ label = "kernel-onenand";
+ reg = <0xe0000 0x200000>;
+ };
+ partition@0x2e0000 {
+ label = "filesystem-onenand";
+ reg = <0x2e0000 0xfd20000>;
+ };
+ };
+};
--- /dev/null
+/*
+ * Device Tree Source for OMAP34xx/OMAP35xx SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "omap3.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ /* OMAP343x/OMAP35xx variants OPP1-5 */
+ operating-points = <
+ /* kHz uV */
+ 125000 975000
+ 250000 1075000
+ 500000 1200000
+ 550000 1270000
+ 600000 1350000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+ };
+ };
+};
serial3 = &uart4;
};
+ cpus {
+ /* OMAP3630/OMAP37xx 'standard device' variants OPP50 to OPP130 */
+ cpu@0 {
+ operating-points = <
+ /* kHz uV */
+ 300000 975000
+ 600000 1075000
+ 800000 1200000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+ };
+ };
+
ocp {
uart4: serial@49042000 {
compatible = "ti,omap3-uart";
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-/include/ "omap4-panda.dts"
+/dts-v1/;
+
+/include/ "omap443x.dtsi"
+/include/ "omap4-panda-common.dtsi"
/* Pandaboard Rev A4+ have external pullups on SCL & SDA */
&dss_hdmi_pins {
--- /dev/null
+/*
+ * Copyright (C) 2011-2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/include/ "elpida_ecb240abacn.dtsi"
+
+/ {
+ model = "TI OMAP4 PandaBoard";
+ compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ heartbeat {
+ label = "pandaboard::status1";
+ gpios = <&gpio1 7 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ mmc {
+ label = "pandaboard::status2";
+ gpios = <&gpio1 8 0>;
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ sound: sound {
+ compatible = "ti,abe-twl6040";
+ ti,model = "PandaBoard";
+
+ ti,mclk-freq = <38400000>;
+
+ ti,mcpdm = <&mcpdm>;
+
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "Ext Spk", "HFL",
+ "Ext Spk", "HFR",
+ "Line Out", "AUXL",
+ "Line Out", "AUXR",
+ "HSMIC", "Headset Mic",
+ "Headset Mic", "Headset Mic Bias",
+ "AFML", "Line In",
+ "AFMR", "Line In";
+ };
+};
+
+&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &twl6040_pins
+ &mcpdm_pins
+ &mcbsp1_pins
+ &dss_hdmi_pins
+ &tpd12s015_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */
+ 0x160 0x100 /* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0xc6 0x108 /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
+ 0xc8 0x108 /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
+ 0xca 0x118 /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
+ 0xcc 0x108 /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
+ 0xce 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0xbe 0x100 /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
+ 0xc0 0x108 /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
+ 0xc2 0x8 /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
+ 0xc4 0x100 /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ 0x5a 0x118 /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
+ 0x5c 0x118 /* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */
+ 0x5e 0x118 /* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */
+ >;
+ };
+
+ tpd12s015_pins: pinmux_tpd12s015_pins {
+ pinctrl-single,pins = <
+ 0x22 0x3 /* gpmc_a17.gpio_41 OUTPUT | MODE3 */
+ 0x48 0x3 /* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */
+ 0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0xe2 0x118 /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xe4 0x118 /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0xe6 0x118 /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xe8 0x118 /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0xea 0x118 /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xec 0x118 /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ 0xee 0x118 /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xf0 0x118 /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
+ interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
+ interrupt-parent = <&gic>;
+ };
+
+ twl6040: twl@4b {
+ compatible = "ti,twl6040";
+ reg = <0x4b>;
+ /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
+ interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */
+ interrupt-parent = <&gic>;
+ ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */
+
+ vio-supply = <&v1v8>;
+ v2v1-supply = <&v2v1>;
+ enable-active-high;
+ };
+};
+
+/include/ "twl6030.dtsi"
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <100000>;
+
+ /*
+ * Display monitor features are burnt in their EEPROM as EDID data.
+ * The EEPROM is connected as I2C slave device.
+ */
+ eeprom@50 {
+ compatible = "ti,eeprom";
+ reg = <0x50>;
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
+ clock-frequency = <400000>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc>;
+ bus-width = <8>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&mmc4 {
+ status = "disabled";
+};
+
+&mmc5 {
+ ti,non-removable;
+ bus-width = <4>;
+};
+
+&emif1 {
+ cs1-used;
+ device-handle = <&elpida_ECB240ABACN>;
+};
+
+&emif2 {
+ cs1-used;
+ device-handle = <&elpida_ECB240ABACN>;
+};
+
+&mcbsp2 {
+ status = "disabled";
+};
+
+&mcbsp3 {
+ status = "disabled";
+};
+
+&dmic {
+ status = "disabled";
+};
+
+&twl_usb_comparator {
+ usb-supply = <&vusb>;
+};
+
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-/include/ "omap4-panda.dts"
+/dts-v1/;
+
+/include/ "omap4460.dtsi"
+/include/ "omap4-panda-common.dtsi"
/* Audio routing is differnet between PandaBoard4430 and PandaBoardES */
&sound {
*/
/dts-v1/;
-/include/ "omap4.dtsi"
-/include/ "elpida_ecb240abacn.dtsi"
-
-/ {
- model = "TI OMAP4 PandaBoard";
- compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
-
- memory {
- device_type = "memory";
- reg = <0x80000000 0x40000000>; /* 1 GB */
- };
-
- leds {
- compatible = "gpio-leds";
- heartbeat {
- label = "pandaboard::status1";
- gpios = <&gpio1 7 0>;
- linux,default-trigger = "heartbeat";
- };
-
- mmc {
- label = "pandaboard::status2";
- gpios = <&gpio1 8 0>;
- linux,default-trigger = "mmc0";
- };
- };
-
- sound: sound {
- compatible = "ti,abe-twl6040";
- ti,model = "PandaBoard";
-
- ti,mclk-freq = <38400000>;
-
- ti,mcpdm = <&mcpdm>;
-
- ti,twl6040 = <&twl6040>;
-
- /* Audio routing */
- ti,audio-routing =
- "Headset Stereophone", "HSOL",
- "Headset Stereophone", "HSOR",
- "Ext Spk", "HFL",
- "Ext Spk", "HFR",
- "Line Out", "AUXL",
- "Line Out", "AUXR",
- "HSMIC", "Headset Mic",
- "Headset Mic", "Headset Mic Bias",
- "AFML", "Line In",
- "AFMR", "Line In";
- };
-};
-
-&omap4_pmx_core {
- pinctrl-names = "default";
- pinctrl-0 = <
- &twl6040_pins
- &mcpdm_pins
- &mcbsp1_pins
- &dss_hdmi_pins
- &tpd12s015_pins
- >;
-
- twl6040_pins: pinmux_twl6040_pins {
- pinctrl-single,pins = <
- 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */
- 0x160 0x100 /* sys_nirq2.sys_nirq2 INPUT | MODE0 */
- >;
- };
-
- mcpdm_pins: pinmux_mcpdm_pins {
- pinctrl-single,pins = <
- 0xc6 0x108 /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
- 0xc8 0x108 /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
- 0xca 0x118 /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
- 0xcc 0x108 /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
- 0xce 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
- >;
- };
-
- mcbsp1_pins: pinmux_mcbsp1_pins {
- pinctrl-single,pins = <
- 0xbe 0x100 /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
- 0xc0 0x108 /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
- 0xc2 0x8 /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
- 0xc4 0x100 /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
- >;
- };
-
- dss_hdmi_pins: pinmux_dss_hdmi_pins {
- pinctrl-single,pins = <
- 0x5a 0x118 /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
- 0x5c 0x118 /* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */
- 0x5e 0x118 /* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */
- >;
- };
-
- tpd12s015_pins: pinmux_tpd12s015_pins {
- pinctrl-single,pins = <
- 0x22 0x3 /* gpmc_a17.gpio_41 OUTPUT | MODE3 */
- 0x48 0x3 /* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */
- 0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
- >;
- };
-};
-
-&i2c1 {
- clock-frequency = <400000>;
-
- twl: twl@48 {
- reg = <0x48>;
- /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
- interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
- interrupt-parent = <&gic>;
- };
-
- twl6040: twl@4b {
- compatible = "ti,twl6040";
- reg = <0x4b>;
- /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
- interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */
- interrupt-parent = <&gic>;
- ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */
-
- vio-supply = <&v1v8>;
- v2v1-supply = <&v2v1>;
- enable-active-high;
- };
-};
-
-/include/ "twl6030.dtsi"
-
-&i2c2 {
- clock-frequency = <400000>;
-};
-
-&i2c3 {
- clock-frequency = <100000>;
-
- /*
- * Display monitor features are burnt in their EEPROM as EDID data.
- * The EEPROM is connected as I2C slave device.
- */
- eeprom@50 {
- compatible = "ti,eeprom";
- reg = <0x50>;
- };
-};
-
-&i2c4 {
- clock-frequency = <400000>;
-};
-
-&mmc1 {
- vmmc-supply = <&vmmc>;
- bus-width = <8>;
-};
-
-&mmc2 {
- status = "disabled";
-};
-
-&mmc3 {
- status = "disabled";
-};
-
-&mmc4 {
- status = "disabled";
-};
-
-&mmc5 {
- ti,non-removable;
- bus-width = <4>;
-};
-
-&emif1 {
- cs1-used;
- device-handle = <&elpida_ECB240ABACN>;
-};
-
-&emif2 {
- cs1-used;
- device-handle = <&elpida_ECB240ABACN>;
-};
-
-&mcbsp2 {
- status = "disabled";
-};
-
-&mcbsp3 {
- status = "disabled";
-};
-
-&dmic {
- status = "disabled";
-};
-
-&twl_usb_comparator {
- usb-supply = <&vusb>;
-};
+/include/ "omap443x.dtsi"
+/include/ "omap4-panda-common.dtsi"
*/
/dts-v1/;
-/include/ "omap4.dtsi"
+/include/ "omap443x.dtsi"
/include/ "elpida_ecb240abacn.dtsi"
/ {
};
};
+ pwmleds {
+ compatible = "pwm-leds";
+ kpad {
+ label = "omap4::keypad";
+ pwms = <&twl_pwm 0 7812500>;
+ max-brightness = <127>;
+ };
+
+ charging {
+ label = "omap4:green:chrg";
+ pwms = <&twl_pwmled 0 7812500>;
+ max-brightness = <255>;
+ };
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&twl_pwm 1 7812500>;
+ brightness-levels = <
+ 0 10 20 30 40
+ 50 60 70 80 90
+ 100 110 120 127
+ >;
+ default-brightness-level = <13>;
+ };
+
sound {
compatible = "ti,abe-twl6040";
ti,model = "SDP4430";
0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
>;
};
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0xe2 0x118 /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xe4 0x118 /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0xe6 0x118 /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xe8 0x118 /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0xea 0x118 /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xec 0x118 /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ 0xee 0x118 /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */
+ 0xf0 0x118 /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
};
&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
clock-frequency = <400000>;
twl: twl@48 {
/include/ "twl6030.dtsi"
&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
clock-frequency = <400000>;
};
&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
clock-frequency = <400000>;
/*
};
&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
clock-frequency = <400000>;
/*
&twl_usb_comparator {
usb-supply = <&vusb>;
};
+
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
*/
/dts-v1/;
-/include/ "omap4.dtsi"
+/include/ "omap443x.dtsi"
/ {
model = "Variscite OMAP4 SOM";
#size-cells = <1>;
ranges;
ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+ reg = <0x44000000 0x1000>,
+ <0x44800000 0x2000>,
+ <0x45000000 0x1000>;
+ interrupts = <0 9 0x4>,
+ <0 10 0x4>;
counter32k: counter@4a304000 {
compatible = "ti,omap-counter32k";
pinctrl-single,function-mask = <0x7fff>;
};
+ sdma: dma-controller@4a056000 {
+ compatible = "ti,omap4430-sdma";
+ reg = <0x4a056000 0x1000>;
+ interrupts = <0 12 0x4>,
+ <0 13 0x4>,
+ <0 14 0x4>,
+ <0 15 0x4>;
+ #dma-cells = <1>;
+ #dma-channels = <32>;
+ #dma-requests = <127>;
+ };
+
gpio1: gpio@4a310000 {
compatible = "ti,omap4-gpio";
reg = <0x4a310000 0x200>;
interrupts = <0 29 0x4>;
ti,hwmods = "gpio1";
+ ti,gpio-always-on;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio2: gpio@48055000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio3: gpio@48057000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio4: gpio@48059000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio5: gpio@4805b000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio6: gpio@4805d000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,omap4430-gpmc";
+ reg = <0x50000000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <0 20 0x4>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
};
uart1: serial@4806a000 {
#size-cells = <0>;
ti,hwmods = "mcspi1";
ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
};
mcspi2: spi@4809a000 {
#size-cells = <0>;
ti,hwmods = "mcspi2";
ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
};
mcspi3: spi@480b8000 {
#size-cells = <0>;
ti,hwmods = "mcspi3";
ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>, <&sdma 16>;
+ dma-names = "tx0", "rx0";
};
mcspi4: spi@480ba000 {
#size-cells = <0>;
ti,hwmods = "mcspi4";
ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
};
mmc1: mmc@4809c000 {
ti,hwmods = "mmc1";
ti,dual-volt;
ti,needs-special-reset;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
};
mmc2: mmc@480b4000 {
interrupts = <0 86 0x4>;
ti,hwmods = "mmc2";
ti,needs-special-reset;
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
};
mmc3: mmc@480ad000 {
interrupts = <0 94 0x4>;
ti,hwmods = "mmc3";
ti,needs-special-reset;
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
};
mmc4: mmc@480d1000 {
interrupts = <0 96 0x4>;
ti,hwmods = "mmc4";
ti,needs-special-reset;
+ dmas = <&sdma 57>, <&sdma 58>;
+ dma-names = "tx", "rx";
};
mmc5: mmc@480d5000 {
interrupts = <0 59 0x4>;
ti,hwmods = "mmc5";
ti,needs-special-reset;
+ dmas = <&sdma 59>, <&sdma 60>;
+ dma-names = "tx", "rx";
};
wdt2: wdt@4a314000 {
reg-names = "mpu", "dma";
interrupts = <0 112 0x4>;
ti,hwmods = "mcpdm";
+ dmas = <&sdma 65>,
+ <&sdma 66>;
+ dma-names = "up_link", "dn_link";
};
dmic: dmic@4012e000 {
reg-names = "mpu", "dma";
interrupts = <0 114 0x4>;
ti,hwmods = "dmic";
+ dmas = <&sdma 67>;
+ dma-names = "up_link";
};
mcbsp1: mcbsp@40122000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp1";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
};
mcbsp2: mcbsp@40124000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp2";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
};
mcbsp3: mcbsp@40126000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp3";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
};
mcbsp4: mcbsp@48096000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp4";
+ dmas = <&sdma 31>,
+ <&sdma 32>;
+ dma-names = "tx", "rx";
};
keypad: keypad@4a31c000 {
#size-cells = <1>;
ranges;
ti,hwmods = "ocp2scp_usb_phy";
+ usb2_phy: usb2phy@4a0ad080 {
+ compatible = "ti,omap-usb2";
+ reg = <0x4a0ad080 0x58>;
+ ctrl-module = <&omap_control_usb>;
+ };
};
timer1: timer@4a318000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x4a318000 0x80>;
interrupts = <0 37 0x4>;
ti,hwmods = "timer1";
};
timer2: timer@48032000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48032000 0x80>;
interrupts = <0 38 0x4>;
ti,hwmods = "timer2";
};
timer3: timer@48034000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x48034000 0x80>;
interrupts = <0 39 0x4>;
ti,hwmods = "timer3";
};
timer4: timer@48036000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x48036000 0x80>;
interrupts = <0 40 0x4>;
ti,hwmods = "timer4";
};
timer5: timer@40138000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x40138000 0x80>,
<0x49038000 0x80>;
interrupts = <0 41 0x4>;
};
timer6: timer@4013a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x4013a000 0x80>,
<0x4903a000 0x80>;
interrupts = <0 42 0x4>;
};
timer7: timer@4013c000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x4013c000 0x80>,
<0x4903c000 0x80>;
interrupts = <0 43 0x4>;
};
timer8: timer@4013e000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x4013e000 0x80>,
<0x4903e000 0x80>;
interrupts = <0 44 0x4>;
};
timer9: timer@4803e000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x4803e000 0x80>;
interrupts = <0 45 0x4>;
ti,hwmods = "timer9";
};
timer10: timer@48086000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap3430-timer";
reg = <0x48086000 0x80>;
interrupts = <0 46 0x4>;
ti,hwmods = "timer10";
};
timer11: timer@48088000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap4430-timer";
reg = <0x48088000 0x80>;
interrupts = <0 47 0x4>;
ti,hwmods = "timer11";
ti,timer-pwm;
};
+
+ usbhstll: usbhstll@4a062000 {
+ compatible = "ti,usbhs-tll";
+ reg = <0x4a062000 0x1000>;
+ interrupts = <0 78 0x4>;
+ ti,hwmods = "usb_tll_hs";
+ };
+
+ usbhshost: usbhshost@4a064000 {
+ compatible = "ti,usbhs-host";
+ reg = <0x4a064000 0x800>;
+ ti,hwmods = "usb_host_hs";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usbhsohci: ohci@4a064800 {
+ compatible = "ti,ohci-omap3", "usb-ohci";
+ reg = <0x4a064800 0x400>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 76 0x4>;
+ };
+
+ usbhsehci: ehci@4a064c00 {
+ compatible = "ti,ehci-omap", "usb-ehci";
+ reg = <0x4a064c00 0x400>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 77 0x4>;
+ };
+ };
+
+ omap_control_usb: omap-control-usb@4a002300 {
+ compatible = "ti,omap-control-usb";
+ reg = <0x4a002300 0x4>,
+ <0x4a00233c 0x4>;
+ reg-names = "control_dev_conf", "otghs_control";
+ ti,type = <1>;
+ };
+
+ usb_otg_hs: usb_otg_hs@4a0ab000 {
+ compatible = "ti,omap4-musb";
+ reg = <0x4a0ab000 0x7ff>;
+ interrupts = <0 92 0x4>, <0 93 0x4>;
+ interrupt-names = "mc", "dma";
+ ti,hwmods = "usb_otg_hs";
+ usb-phy = <&usb2_phy>;
+ multipoint = <1>;
+ num-eps = <16>;
+ ram-bits = <12>;
+ ti,has-mailbox;
+ };
};
};
--- /dev/null
+/*
+ * Device Tree Source for OMAP443x SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "omap4.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ /* OMAP443x variants OPP50-OPPNT */
+ operating-points = <
+ /* kHz uV */
+ 300000 1025000
+ 600000 1200000
+ 800000 1313000
+ 1008000 1375000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+ };
+ };
+};
--- /dev/null
+/*
+ * Device Tree Source for OMAP4460 SoC
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+/include/ "omap4.dtsi"
+
+/ {
+ cpus {
+ /* OMAP446x 'standard device' variants OPP50 to OPPTurbo */
+ cpu@0 {
+ operating-points = <
+ /* kHz uV */
+ 350000 975000
+ 700000 1075000
+ 920000 1200000
+ >;
+ clock-latency = <300000>; /* From legacy driver */
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 54 0x4>,
+ <0 55 0x4>;
+ ti,hwmods = "debugss";
+ };
+};
memory {
device_type = "memory";
- reg = <0x80000000 0x80000000>; /* 2 GB */
+ reg = <0x80000000 0x7F000000>; /* 2032 MB */
};
vmmcsd_fixed: fixedregulator-mmcsd {
0x15a 0x100 /* abemcbsp2_clkx.abemcbsp2_clkx INPUT | MODE0 */
>;
};
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ 0x1b2 0x118 /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
+ 0x1b4 0x118 /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ 0x178 0x100 /* i2c2_scl INPUTENABLE | MODE0 */
+ 0x17a 0x100 /* i2c2_sda INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ 0x13a 0x100 /* i2c3_scl INPUTENABLE | MODE0 */
+ 0x13c 0x100 /* i2c3_sda INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ 0xb8 0x100 /* i2c4_scl INPUTENABLE | MODE0 */
+ 0xba 0x100 /* i2c4_sda INPUTENABLE | MODE0 */
+ >;
+ };
+
+ i2c5_pins: pinmux_i2c5_pins {
+ pinctrl-single,pins = <
+ 0x184 0x100 /* i2c5_scl INPUTENABLE | MODE0 */
+ 0x186 0x100 /* i2c5_sda INPUTENABLE | MODE0 */
+ >;
+ };
+
+ mcspi2_pins: pinmux_mcspi2_pins {
+ pinctrl-single,pins = <
+ 0xbc 0x100 /* MCSPI2_CLK INPUTENABLE | MODE0 */
+ 0xbe 0x100 /* MCSPI2_SIMO INPUTENABLE | MODE0 */
+ 0xc0 0x118 /* MCSPI2_SOMI PULLUP | INPUTENABLE | MODE0*/
+ 0xc2 0x0 /* MCSPI2_CS MODE0*/
+ >;
+ };
+
+ mcspi3_pins: pinmux_mcspi3_pins {
+ pinctrl-single,pins = <
+ 0x78 0x101 /* MCSPI2_SOMI INPUTENABLE | MODE1 */
+ 0x7a 0x101 /* MCSPI2_CS INPUTENABLE | MODE1 */
+ 0x7c 0x101 /* MCSPI2_SIMO INPUTENABLE | MODE1 */
+ 0x7e 0x101 /* MCSPI2_CLK INPUTENABLE | MODE1 */
+ >;
+ };
+
+ mcspi4_pins: pinmux_mcspi4_pins {
+ pinctrl-single,pins = <
+ 0x164 0x101 /* MCSPI2_CLK INPUTENABLE | MODE1 */
+ 0x168 0x101 /* MCSPI2_SIMO INPUTENABLE | MODE1 */
+ 0x16a 0x101 /* MCSPI2_SOMI INPUTENABLE | MODE1 */
+ 0x16c 0x101 /* MCSPI2_CS INPUTENABLE | MODE1 */
+ >;
+ };
};
&mmc1 {
status = "disabled";
};
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ clock-frequency = <400000>;
+};
+
&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
clock-frequency = <400000>;
/* Pressure Sensor */
};
};
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ clock-frequency = <400000>;
+};
+
&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
clock-frequency = <400000>;
/* Temperature Sensor */
};
};
+&i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins>;
+
+ clock-frequency = <400000>;
+};
+
&keypad {
keypad,num-rows = <8>;
keypad,num-columns = <8>;
cs1-used;
device-handle = <&samsung_K3PE0E000B>;
};
+
+&mcspi1 {
+
+};
+
+&mcspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi2_pins>;
+};
+
+&mcspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi3_pins>;
+};
+
+&mcspi4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi4_pins>;
+};
/include/ "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
compatible = "ti,omap5";
interrupt-parent = <&gic>;
cpus {
cpu@0 {
compatible = "arm,cortex-a15";
- timer {
- compatible = "arm,armv7-timer";
- /* 14th PPI IRQ, active low level-sensitive */
- interrupts = <1 14 0x308>;
- clock-frequency = <6144000>;
- };
};
cpu@1 {
compatible = "arm,cortex-a15";
- timer {
- compatible = "arm,armv7-timer";
- /* 14th PPI IRQ, active low level-sensitive */
- interrupts = <1 14 0x308>;
- clock-frequency = <6144000>;
- };
};
};
+ timer {
+ compatible = "arm,armv7-timer";
+ /* PPI secure/nonsecure IRQ, active low level-sensitive */
+ interrupts = <1 13 0x308>,
+ <1 14 0x308>,
+ <1 11 0x308>,
+ <1 10 0x308>;
+ clock-frequency = <6144000>;
+ };
+
+ gic: interrupt-controller@48211000 {
+ compatible = "arm,cortex-a15-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x48211000 0x1000>,
+ <0x48212000 0x1000>,
+ <0x48214000 0x2000>,
+ <0x48216000 0x2000>;
+ };
+
/*
* The soc node represents the soc top level view. It is uses for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
#size-cells = <1>;
ranges;
ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+ reg = <0x44000000 0x2000>,
+ <0x44800000 0x3000>,
+ <0x45000000 0x4000>;
+ interrupts = <0 9 0x4>,
+ <0 10 0x4>;
counter32k: counter@4ae04000 {
compatible = "ti,omap-counter32k";
pinctrl-single,function-mask = <0x7fff>;
};
- gic: interrupt-controller@48211000 {
- compatible = "arm,cortex-a15-gic";
- interrupt-controller;
- #interrupt-cells = <3>;
- reg = <0x48211000 0x1000>,
- <0x48212000 0x1000>;
+ sdma: dma-controller@4a056000 {
+ compatible = "ti,omap4430-sdma";
+ reg = <0x4a056000 0x1000>;
+ interrupts = <0 12 0x4>,
+ <0 13 0x4>,
+ <0 14 0x4>,
+ <0 15 0x4>;
+ #dma-cells = <1>;
+ #dma-channels = <32>;
+ #dma-requests = <127>;
};
gpio1: gpio@4ae10000 {
reg = <0x4ae10000 0x200>;
interrupts = <0 29 0x4>;
ti,hwmods = "gpio1";
+ ti,gpio-always-on;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio2: gpio@48055000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio3: gpio@48057000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio4: gpio@48059000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio5: gpio@4805b000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio6: gpio@4805d000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio7: gpio@48051000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
};
gpio8: gpio@48053000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,omap4430-gpmc";
+ reg = <0x50000000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <0 20 0x4>;
+ gpmc,num-cs = <8>;
+ gpmc,num-waitpins = <4>;
+ ti,hwmods = "gpmc";
};
i2c1: i2c@48070000 {
ti,hwmods = "i2c5";
};
+ mcspi1: spi@48098000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x48098000 0x200>;
+ interrupts = <0 65 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi1";
+ ti,spi-num-cs = <4>;
+ dmas = <&sdma 35>,
+ <&sdma 36>,
+ <&sdma 37>,
+ <&sdma 38>,
+ <&sdma 39>,
+ <&sdma 40>,
+ <&sdma 41>,
+ <&sdma 42>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
+ };
+
+ mcspi2: spi@4809a000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x4809a000 0x200>;
+ interrupts = <0 66 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi2";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 43>,
+ <&sdma 44>,
+ <&sdma 45>,
+ <&sdma 46>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mcspi3: spi@480b8000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480b8000 0x200>;
+ interrupts = <0 91 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi3";
+ ti,spi-num-cs = <2>;
+ dmas = <&sdma 15>, <&sdma 16>;
+ dma-names = "tx0", "rx0";
+ };
+
+ mcspi4: spi@480ba000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x480ba000 0x200>;
+ interrupts = <0 48 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ti,hwmods = "mcspi4";
+ ti,spi-num-cs = <1>;
+ dmas = <&sdma 70>, <&sdma 71>;
+ dma-names = "tx0", "rx0";
+ };
+
uart1: serial@4806a000 {
compatible = "ti,omap4-uart";
reg = <0x4806a000 0x100>;
ti,hwmods = "mmc1";
ti,dual-volt;
ti,needs-special-reset;
+ dmas = <&sdma 61>, <&sdma 62>;
+ dma-names = "tx", "rx";
};
mmc2: mmc@480b4000 {
interrupts = <0 86 0x4>;
ti,hwmods = "mmc2";
ti,needs-special-reset;
+ dmas = <&sdma 47>, <&sdma 48>;
+ dma-names = "tx", "rx";
};
mmc3: mmc@480ad000 {
interrupts = <0 94 0x4>;
ti,hwmods = "mmc3";
ti,needs-special-reset;
+ dmas = <&sdma 77>, <&sdma 78>;
+ dma-names = "tx", "rx";
};
mmc4: mmc@480d1000 {
interrupts = <0 96 0x4>;
ti,hwmods = "mmc4";
ti,needs-special-reset;
+ dmas = <&sdma 57>, <&sdma 58>;
+ dma-names = "tx", "rx";
};
mmc5: mmc@480d5000 {
interrupts = <0 59 0x4>;
ti,hwmods = "mmc5";
ti,needs-special-reset;
+ dmas = <&sdma 59>, <&sdma 60>;
+ dma-names = "tx", "rx";
};
keypad: keypad@4ae1c000 {
compatible = "ti,omap4-keypad";
+ reg = <0x4ae1c000 0x400>;
ti,hwmods = "kbd";
};
reg-names = "mpu", "dma";
interrupts = <0 112 0x4>;
ti,hwmods = "mcpdm";
+ dmas = <&sdma 65>,
+ <&sdma 66>;
+ dma-names = "up_link", "dn_link";
};
dmic: dmic@4012e000 {
reg-names = "mpu", "dma";
interrupts = <0 114 0x4>;
ti,hwmods = "dmic";
+ dmas = <&sdma 67>;
+ dma-names = "up_link";
};
mcbsp1: mcbsp@40122000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp1";
+ dmas = <&sdma 33>,
+ <&sdma 34>;
+ dma-names = "tx", "rx";
};
mcbsp2: mcbsp@40124000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp2";
+ dmas = <&sdma 17>,
+ <&sdma 18>;
+ dma-names = "tx", "rx";
};
mcbsp3: mcbsp@40126000 {
interrupt-names = "common";
ti,buffer-size = <128>;
ti,hwmods = "mcbsp3";
+ dmas = <&sdma 19>,
+ <&sdma 20>;
+ dma-names = "tx", "rx";
};
timer1: timer@4ae18000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x4ae18000 0x80>;
interrupts = <0 37 0x4>;
ti,hwmods = "timer1";
};
timer2: timer@48032000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x48032000 0x80>;
interrupts = <0 38 0x4>;
ti,hwmods = "timer2";
};
timer3: timer@48034000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x48034000 0x80>;
interrupts = <0 39 0x4>;
ti,hwmods = "timer3";
};
timer4: timer@48036000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x48036000 0x80>;
interrupts = <0 40 0x4>;
ti,hwmods = "timer4";
};
timer5: timer@40138000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x40138000 0x80>,
<0x49038000 0x80>;
interrupts = <0 41 0x4>;
};
timer6: timer@4013a000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x4013a000 0x80>,
<0x4903a000 0x80>;
interrupts = <0 42 0x4>;
};
timer7: timer@4013c000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x4013c000 0x80>,
<0x4903c000 0x80>;
interrupts = <0 43 0x4>;
};
timer8: timer@4013e000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x4013e000 0x80>,
<0x4903e000 0x80>;
interrupts = <0 44 0x4>;
};
timer9: timer@4803e000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x4803e000 0x80>;
interrupts = <0 45 0x4>;
ti,hwmods = "timer9";
};
timer10: timer@48086000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x48086000 0x80>;
interrupts = <0 46 0x4>;
ti,hwmods = "timer10";
};
timer11: timer@48088000 {
- compatible = "ti,omap2-timer";
+ compatible = "ti,omap5430-timer";
reg = <0x48088000 0x80>;
interrupts = <0 47 0x4>;
ti,hwmods = "timer11";
ti,timer-pwm;
};
+ wdt2: wdt@4ae14000 {
+ compatible = "ti,omap5-wdt", "ti,omap3-wdt";
+ reg = <0x4ae14000 0x80>;
+ interrupts = <0 80 0x4>;
+ ti,hwmods = "wd_timer2";
+ };
+
emif1: emif@0x4c000000 {
compatible = "ti,emif-4d5";
ti,hwmods = "emif1";
hw-caps-ll-interface;
hw-caps-temp-alert;
};
+
+ omap_control_usb: omap-control-usb@4a002300 {
+ compatible = "ti,omap-control-usb";
+ reg = <0x4a002300 0x4>,
+ <0x4a002370 0x4>;
+ reg-names = "control_dev_conf", "phy_power_usb";
+ ti,type = <2>;
+ };
+
+ omap_dwc3@4a020000 {
+ compatible = "ti,dwc3";
+ ti,hwmods = "usb_otg_ss";
+ reg = <0x4a020000 0x1000>;
+ interrupts = <0 93 4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ utmi-mode = <2>;
+ ranges;
+ dwc3@4a030000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x4a030000 0x1000>;
+ interrupts = <0 92 4>;
+ usb-phy = <&usb2_phy>, <&usb3_phy>;
+ tx-fifo-resize;
+ };
+ };
+
+ ocp2scp {
+ compatible = "ti,omap-ocp2scp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "ocp2scp1";
+ usb2_phy: usb2phy@4a084000 {
+ compatible = "ti,omap-usb2";
+ reg = <0x4a084000 0x7c>;
+ ctrl-module = <&omap_control_usb>;
+ };
+
+ usb3_phy: usb3phy@4a084400 {
+ compatible = "ti,omap-usb3";
+ reg = <0x4a084400 0x80>,
+ <0x4a084800 0x64>,
+ <0x4a084c00 0x40>;
+ reg-names = "phy_rx", "phy_tx", "pll_ctrl";
+ ctrl-module = <&omap_control_usb>;
+ };
+ };
};
};
status = "okay";
};
+ ehci@50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <17>;
+ status = "disabled";
+ };
+
+ ehci@a0000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0xa0000 0x1000>;
+ interrupts = <12>;
+ status = "disabled";
+ };
+
sata@80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
status = "disabled";
};
+ xor@60900 {
+ compatible = "marvell,orion-xor";
+ reg = <0x60900 0x100
+ 0x60b00 0x100>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <30>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <31>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
crypto@90000 {
compatible = "marvell,orion-crypto";
reg = <0x90000 0x10000>,
--- /dev/null
+/*
+ * Skeleton device tree in the 64 bits version; the bare minimum
+ * needed to boot; just include and add a compatible value. The
+ * bootloader will typically populate the memory node.
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0>; };
+};
reg = <0x80000000 0x40000000>;
};
+ pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ dap1_din_pn1 {
+ nvidia,pins = "dap1_din_pn1";
+ nvidia,function = "i2s0";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ dap1_dout_pn2 {
+ nvidia,pins = "dap1_dout_pn2",
+ "dap1_fs_pn0",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ dap2_din_pa4 {
+ nvidia,pins = "dap2_din_pa4";
+ nvidia,function = "i2s1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ dap2_dout_pa5 {
+ nvidia,pins = "dap2_dout_pa5",
+ "dap2_fs_pa2",
+ "dap2_sclk_pa3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ dap4_din_pp5 {
+ nvidia,pins = "dap4_din_pp5",
+ "dap4_dout_pp6",
+ "dap4_fs_pp4",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ dvfs_pwm_px0 {
+ nvidia,pins = "dvfs_pwm_px0",
+ "dvfs_clk_px2";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_data0_po1",
+ "ulpi_data1_po2",
+ "ulpi_data2_po3",
+ "ulpi_data3_po4",
+ "ulpi_data4_po5",
+ "ulpi_data5_po6",
+ "ulpi_data6_po7",
+ "ulpi_data7_po0";
+ nvidia,function = "ulpi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1",
+ "ulpi_nxt_py2";
+ nvidia,function = "ulpi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ ulpi_stp_py3 {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "ulpi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,open-drain = <0>;
+ };
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0",
+ "pbb0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ nvidia,lock = <0>;
+ };
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,open-drain = <0>;
+ };
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7";
+ nvidia,function = "uartd";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gmi_a17_pb0 {
+ nvidia,pins = "gmi_a17_pb0",
+ "gmi_a18_pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ gmi_a19_pk7 {
+ nvidia,pins = "gmi_a19_pk7";
+ nvidia,function = "uartd";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gmi_ad5_pg5 {
+ nvidia,pins = "gmi_ad5_pg5",
+ "gmi_cs6_n_pi3",
+ "gmi_wr_n_pi0";
+ nvidia,function = "spi4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gmi_ad6_pg6 {
+ nvidia,pins = "gmi_ad6_pg6",
+ "gmi_ad7_pg7";
+ nvidia,function = "spi4";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gmi_ad12_ph4 {
+ nvidia,pins = "gmi_ad12_ph4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gmi_ad9_ph1 {
+ nvidia,pins = "gmi_ad9_ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gmi_cs1_n_pj2 {
+ nvidia,pins = "gmi_cs1_n_pj2",
+ "gmi_oe_n_pi1";
+ nvidia,function = "soc";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "extperiph2";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ sdmmc1_cmd_pz1 {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat3_py4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ sdmmc1_wp_n_pv3 {
+ nvidia,pins = "sdmmc1_wp_n_pv3";
+ nvidia,function = "spi4";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4",
+ "kb_col4_pq4",
+ "sdmmc3_clk_lb_out_pee4",
+ "sdmmc3_clk_lb_in_pee5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,function = "blink";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ kb_col0_pq0 {
+ nvidia,pins = "kb_col0_pq0",
+ "kb_col1_pq1",
+ "kb_col2_pq2",
+ "kb_row0_pr0",
+ "kb_row1_pr1",
+ "kb_row2_pr2";
+ nvidia,function = "kbc";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ dap3_din_pp1 {
+ nvidia,pins = "dap3_din_pp1",
+ "dap3_sclk_pp3";
+ nvidia,function = "displayb";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <0>;
+ };
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <0>;
+ };
+ kb_row7_pr7 {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ kb_row10_ps2 {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "uarta";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ kb_row9_ps1 {
+ nvidia,pins = "kb_row9_ps1";
+ nvidia,function = "uarta";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,open-drain = <0>;
+ };
+ sys_clk_req_pz5 {
+ nvidia,pins = "sys_clk_req_pz5";
+ nvidia,function = "sysclk";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ core_pwr_req {
+ nvidia,pins = "core_pwr_req";
+ nvidia,function = "pwron";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ cpu_pwr_req {
+ nvidia,pins = "cpu_pwr_req";
+ nvidia,function = "cpu";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ reset_out_n {
+ nvidia,pins = "reset_out_n";
+ nvidia,function = "reset_out_n";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4",
+ "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,open-drain = <0>;
+ };
+ uart2_cts_n_pj5 {
+ nvidia,pins = "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ uart2_rts_n_pj6 {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "irda";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "irda";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "owr";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,open-drain = <0>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,rcv-sel = <1>;
+ };
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,function = "usb";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4";
+ nvidia,function = "usb";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ nvidia,lock = <0>;
+ nvidia,open-drain = <1>;
+ };
+ gpio_x6_aud_px6 {
+ nvidia,pins = "gpio_x6_aud_px6";
+ nvidia,function = "spi6";
+ nvidia,pull = <2>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <1>;
+ };
+ gpio_x4_aud_px4 {
+ nvidia,pins = "gpio_x4_aud_px4",
+ "gpio_x7_aud_px7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gpio_x5_aud_px5 {
+ nvidia,pins = "gpio_x5_aud_px5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gpio_w2_aud_pw2 {
+ nvidia,pins = "gpio_w2_aud_pw2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gpio_w3_aud_pw3 {
+ nvidia,pins = "gpio_w3_aud_pw3";
+ nvidia,function = "spi6";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gpio_x1_aud_px1 {
+ nvidia,pins = "gpio_x1_aud_px1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gpio_x3_aud_px3 {
+ nvidia,pins = "gpio_x3_aud_px3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ dap3_dout_pp2 {
+ nvidia,pins = "dap3_dout_pp2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ pbb3 {
+ nvidia,pins = "pbb3",
+ "pbb5",
+ "pbb6",
+ "pbb7";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ pcc1 {
+ nvidia,pins = "pcc1",
+ "pcc2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gmi_ad0_pg0 {
+ nvidia,pins = "gmi_ad0_pg0",
+ "gmi_ad1_pg1";
+ nvidia,function = "gmi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gmi_ad10_ph2 {
+ nvidia,pins = "gmi_ad10_ph2",
+ "gmi_ad11_ph3",
+ "gmi_ad13_ph5",
+ "gmi_ad8_ph0",
+ "gmi_clk_pk1";
+ nvidia,function = "gmi";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ gmi_ad2_pg2 {
+ nvidia,pins = "gmi_ad2_pg2",
+ "gmi_ad3_pg3";
+ nvidia,function = "gmi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gmi_adv_n_pk0 {
+ nvidia,pins = "gmi_adv_n_pk0",
+ "gmi_cs0_n_pj0",
+ "gmi_cs2_n_pk3",
+ "gmi_cs4_n_pk2",
+ "gmi_cs7_n_pi6",
+ "gmi_dqs_p_pj3",
+ "gmi_iordy_pi5",
+ "gmi_wp_n_pc7";
+ nvidia,function = "gmi";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ gmi_cs3_n_pk4 {
+ nvidia,pins = "gmi_cs3_n_pk4";
+ nvidia,function = "gmi";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ kb_col3_pq3 {
+ nvidia,pins = "kb_col3_pq3",
+ "kb_col6_pq6",
+ "kb_col7_pq7";
+ nvidia,function = "kbc";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ kb_col5_pq5 {
+ nvidia,pins = "kb_col5_pq5";
+ nvidia,function = "kbc";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ kb_row3_pr3 {
+ nvidia,pins = "kb_row3_pr3",
+ "kb_row4_pr4",
+ "kb_row6_pr6",
+ "kb_row8_ps0";
+ nvidia,function = "kbc";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,function = "displayb";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <0>;
+ };
+ pu5 {
+ nvidia,pins = "pu5",
+ "pu6";
+ nvidia,function = "displayb";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <1>;
+ nvidia,tristate = <0>;
+ nvidia,enable-input = <1>;
+ };
+ clk1_req_pee2 {
+ nvidia,pins = "clk1_req_pee2",
+ "usb_vbus_en1_pn5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <1>;
+ nvidia,tristate = <1>;
+ nvidia,enable-input = <0>;
+ };
+
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <1>;
+ nvidia,schmitt = <0>;
+ nvidia,low-power-mode = <3>;
+ nvidia,pull-down-strength = <36>;
+ nvidia,pull-up-strength = <20>;
+ nvidia,slew-rate-rising = <2>;
+ nvidia,slew-rate-falling = <2>;
+ };
+ drive_sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <1>;
+ nvidia,schmitt = <0>;
+ nvidia,low-power-mode = <3>;
+ nvidia,pull-down-strength = <22>;
+ nvidia,pull-up-strength = <36>;
+ nvidia,slew-rate-rising = <0>;
+ nvidia,slew-rate-falling = <0>;
+ };
+ drive_gma {
+ nvidia,pins = "drive_gma";
+ nvidia,high-speed-mode = <1>;
+ nvidia,schmitt = <0>;
+ nvidia,low-power-mode = <3>;
+ nvidia,pull-down-strength = <2>;
+ nvidia,pull-up-strength = <1>;
+ nvidia,slew-rate-rising = <0>;
+ nvidia,slew-rate-falling = <0>;
+ nvidia,drive-type = <1>;
+ };
+ };
+ };
+
serial@70006300 {
status = "okay";
- clock-frequency = <408000000>;
+ };
+
+ i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ battery: smart-battery {
+ compatible = "ti,bq20z45", "sbs,sbs-battery";
+ reg = <0xb>;
+ battery-name = "battery";
+ sbs,i2c-retry-count = <2>;
+ sbs,poll-retry-count = <100>;
+ };
+ };
+
+ i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps51632 {
+ compatible = "ti,tps51632";
+ reg = <0x43>;
+ regulator-name = "vdd-cpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1520000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ tps65090 {
+ compatible = "ti,tps65090";
+ reg = <0x48>;
+ interrupt-parent = <&gpio>;
+ interrupts = <72 0x04>; /* gpio PJ0 */
+
+ vsys1-supply = <&vdd_ac_bat_reg>;
+ vsys2-supply = <&vdd_ac_bat_reg>;
+ vsys3-supply = <&vdd_ac_bat_reg>;
+ infet1-supply = <&vdd_ac_bat_reg>;
+ infet2-supply = <&vdd_ac_bat_reg>;
+ infet3-supply = <&tps65090_dcdc2_reg>;
+ infet4-supply = <&tps65090_dcdc2_reg>;
+ infet5-supply = <&tps65090_dcdc2_reg>;
+ infet6-supply = <&tps65090_dcdc2_reg>;
+ infet7-supply = <&tps65090_dcdc2_reg>;
+ vsys-l1-supply = <&vdd_ac_bat_reg>;
+ vsys-l2-supply = <&vdd_ac_bat_reg>;
+
+ regulators {
+ tps65090_dcdc1_reg: dcdc1 {
+ regulator-name = "vdd-sys-5v0";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ tps65090_dcdc2_reg: dcdc2 {
+ regulator-name = "vdd-sys-3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ dcdc3 {
+ regulator-name = "vdd-ao";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ fet1 {
+ regulator-name = "vdd-lcd-bl";
+ };
+
+ fet3 {
+ regulator-name = "vdd-modem-3v3";
+ };
+
+ fet4 {
+ regulator-name = "avdd-lcd";
+ };
+
+ fet5 {
+ regulator-name = "vdd-lvds";
+ };
+
+ fet6 {
+ regulator-name = "vdd-sd-slot";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ fet7 {
+ regulator-name = "vdd-com-3v3";
+ };
+
+ ldo1 {
+ regulator-name = "vdd-sby-5v0";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo2 {
+ regulator-name = "vdd-sby-3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
};
pmc {
nvidia,invert-interrupt;
};
+
+ sdhci@78000400 {
+ cd-gpios = <&gpio 170 1>; /* gpio PV2 */
+ bus-width = <4>;
+ status = "okay";
+ };
+
+ sdhci@78000600 {
+ bus-width = <8>;
+ status = "okay";
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_ac_bat_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vdd_ac_bat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ dvdd_ts_reg: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "dvdd_ts";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ gpio = <&gpio 61 0>; /* GPIO PH5 */
+ };
+
+ lcd_bl_en_reg: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "lcd_bl_en";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio 58 0>; /* GPIO PH2 */
+ };
+
+ usb1_vbus_reg: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "usb1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio 108 0>; /* GPIO PN4 */
+ gpio-open-drain;
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+
+ usb3_vbus_reg: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "usb2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio 86 0>; /* GPIO PK6 */
+ gpio-open-drain;
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+
+ vdd_hdmi_reg: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "vdd_hdmi_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio 81 0>; /* GPIO PK1 */
+ vin-supply = <&tps65090_dcdc1_reg>;
+ };
+ };
};
serial@70006300 {
status = "okay";
- clock-frequency = <408000000>;
};
pmc {
nvidia,invert-interrupt;
};
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
};
compatible = "nvidia,tegra114";
interrupt-parent = <&gic>;
+ aliases {
+ serial0 = &uarta;
+ serial1 = &uartb;
+ serial2 = &uartc;
+ serial3 = &uartd;
+ };
+
gic: interrupt-controller {
compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>;
0 42 0x04
0 121 0x04
0 122 0x04>;
+ clocks = <&tegra_car 5>;
};
tegra_car: clock {
- compatible = "nvidia,tegra114-car, nvidia,tegra30-car";
+ compatible = "nvidia,tegra114-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
};
+ apbdma: dma {
+ compatible = "nvidia,tegra114-apbdma";
+ reg = <0x6000a000 0x1400>;
+ interrupts = <0 104 0x04
+ 0 105 0x04
+ 0 106 0x04
+ 0 107 0x04
+ 0 108 0x04
+ 0 109 0x04
+ 0 110 0x04
+ 0 111 0x04
+ 0 112 0x04
+ 0 113 0x04
+ 0 114 0x04
+ 0 115 0x04
+ 0 116 0x04
+ 0 117 0x04
+ 0 118 0x04
+ 0 119 0x04
+ 0 128 0x04
+ 0 129 0x04
+ 0 130 0x04
+ 0 131 0x04
+ 0 132 0x04
+ 0 133 0x04
+ 0 134 0x04
+ 0 135 0x04
+ 0 136 0x04
+ 0 137 0x04
+ 0 138 0x04
+ 0 139 0x04
+ 0 140 0x04
+ 0 141 0x04
+ 0 142 0x04
+ 0 143 0x04>;
+ clocks = <&tegra_car 34>;
+ };
+
ahb: ahb {
compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb";
reg = <0x6000c004 0x14c>;
0x70003000 0x40c>; /* Mux registers */
};
- serial@70006000 {
+ /*
+ * There are two serial driver i.e. 8250 based simple serial
+ * driver and APB DMA based serial driver for higher baudrate
+ * and performace. To enable the 8250 based driver, the compatible
+ * is "nvidia,tegra114-uart", "nvidia,tegra20-uart" and to enable
+ * the APB DMA based serial driver, the comptible is
+ * "nvidia,tegra114-hsuart", "nvidia,tegra30-hsuart".
+ */
+ uarta: serial@70006000 {
compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
interrupts = <0 36 0x04>;
+ nvidia,dma-request-selector = <&apbdma 8>;
status = "disabled";
+ clocks = <&tegra_car 6>;
};
- serial@70006040 {
+ uartb: serial@70006040 {
compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
reg = <0x70006040 0x40>;
reg-shift = <2>;
interrupts = <0 37 0x04>;
+ nvidia,dma-request-selector = <&apbdma 9>;
status = "disabled";
+ clocks = <&tegra_car 192>;
};
- serial@70006200 {
+ uartc: serial@70006200 {
compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
reg = <0x70006200 0x100>;
reg-shift = <2>;
interrupts = <0 46 0x04>;
+ nvidia,dma-request-selector = <&apbdma 10>;
status = "disabled";
+ clocks = <&tegra_car 55>;
};
- serial@70006300 {
+ uartd: serial@70006300 {
compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
reg = <0x70006300 0x100>;
reg-shift = <2>;
interrupts = <0 90 0x04>;
+ nvidia,dma-request-selector = <&apbdma 19>;
+ status = "disabled";
+ clocks = <&tegra_car 65>;
+ };
+
+ pwm: pwm {
+ compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car 17>;
+ status = "disabled";
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <0 38 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 12>;
+ clock-names = "div-clk";
+ status = "disabled";
+ };
+
+ i2c@7000c400 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <0 84 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 54>;
+ clock-names = "div-clk";
+ status = "disabled";
+ };
+
+ i2c@7000c500 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <0 92 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 67>;
+ clock-names = "div-clk";
+ status = "disabled";
+ };
+
+ i2c@7000c700 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000c700 0x100>;
+ interrupts = <0 120 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 103>;
+ clock-names = "div-clk";
+ status = "disabled";
+ };
+
+ i2c@7000d000 {
+ compatible = "nvidia,tegra114-i2c";
+ reg = <0x7000d000 0x100>;
+ interrupts = <0 53 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 47>;
+ clock-names = "div-clk";
+ status = "disabled";
+ };
+
+ spi@7000d400 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d400 0x200>;
+ interrupts = <0 59 0x04>;
+ nvidia,dma-request-selector = <&apbdma 15>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 41>;
+ clock-names = "spi";
+ status = "disabled";
+ };
+
+ spi@7000d600 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d600 0x200>;
+ interrupts = <0 82 0x04>;
+ nvidia,dma-request-selector = <&apbdma 16>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 44>;
+ clock-names = "spi";
+ status = "disabled";
+ };
+
+ spi@7000d800 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000d800 0x200>;
+ interrupts = <0 83 0x04>;
+ nvidia,dma-request-selector = <&apbdma 17>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 46>;
+ clock-names = "spi";
+ status = "disabled";
+ };
+
+ spi@7000da00 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000da00 0x200>;
+ interrupts = <0 93 0x04>;
+ nvidia,dma-request-selector = <&apbdma 18>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 68>;
+ clock-names = "spi";
+ status = "disabled";
+ };
+
+ spi@7000dc00 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000dc00 0x200>;
+ interrupts = <0 94 0x04>;
+ nvidia,dma-request-selector = <&apbdma 27>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 104>;
+ clock-names = "spi";
+ status = "disabled";
+ };
+
+ spi@7000de00 {
+ compatible = "nvidia,tegra114-spi";
+ reg = <0x7000de00 0x200>;
+ interrupts = <0 79 0x04>;
+ nvidia,dma-request-selector = <&apbdma 28>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 105>;
+ clock-names = "spi";
status = "disabled";
};
compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
+ clocks = <&tegra_car 4>;
+ };
+
+ kbc {
+ compatible = "nvidia,tegra114-kbc";
+ reg = <0x7000e200 0x100>;
+ interrupts = <0 85 0x04>;
+ clocks = <&tegra_car 36>;
+ status = "disabled";
};
pmc {
- compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc";
+ compatible = "nvidia,tegra114-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car 261>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
};
iommu {
nvidia,ahb = <&ahb>;
};
+ sdhci@78000000 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000000 0x200>;
+ interrupts = <0 14 0x04>;
+ clocks = <&tegra_car 14>;
+ status = "disable";
+ };
+
+ sdhci@78000200 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000200 0x200>;
+ interrupts = <0 15 0x04>;
+ clocks = <&tegra_car 9>;
+ status = "disable";
+ };
+
+ sdhci@78000400 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000400 0x200>;
+ interrupts = <0 19 0x04>;
+ clocks = <&tegra_car 69>;
+ status = "disable";
+ };
+
+ sdhci@78000600 {
+ compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+ reg = <0x78000600 0x200>;
+ interrupts = <0 31 0x04>;
+ clocks = <&tegra_car 15>;
+ status = "disable";
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
};
};
+ pmc {
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
memory-controller@7000f400 {
emc-table@83250 {
reg = <83250>;
};
sdhci@c8000600 {
- cd-gpios = <&gpio 23 0>; /* gpio PC7 */
+ cd-gpios = <&gpio 23 1>; /* gpio PC7 */
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
sound {
"Mic", "MIC1";
nvidia,ac97-controller = <&ac97>;
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
regulators {
pmc {
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
};
usb@c5000000 {
sdhci@c8000200 {
status = "okay";
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ cd-gpios = <&gpio 69 1>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 155 0>; /* gpio PT3 */
bus-width = <4>;
sdhci@c8000600 {
status = "okay";
- cd-gpios = <&gpio 58 0>; /* gpio PH2 */
+ cd-gpios = <&gpio 58 1>; /* gpio PH2 */
wp-gpios = <&gpio 59 0>; /* gpio PH3 */
power-gpios = <&gpio 70 0>; /* gpio PI6 */
bus-width = <8>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio 170 1>; /* gpio PV2, active low */
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
+ };
+
kbc {
status = "okay";
nvidia,debounce-delay-ms = <2>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
model = "Avionic Design Medcom-Wide board";
compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20";
+ pwm {
+ status = "okay";
+ };
+
i2c@7000c000 {
wm8903: wm8903@1a {
compatible = "wlf,wm8903";
nvidia,spkr-en-gpios = <&wm8903 2 0>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
pmc {
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <0>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,sys-clock-req-active-high;
};
usb@c5000000 {
sdhci@c8000000 {
status = "okay";
- cd-gpios = <&gpio 173 0>; /* gpio PV5 */
+ cd-gpios = <&gpio 173 1>; /* gpio PV5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 169 0>; /* gpio PV1 */
bus-width = <4>;
sdhci@c8000600 {
status = "okay";
bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
gpio-keys {
nvidia,audio-codec = <&alc5632>;
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
nvidia,spkr-en-gpios = <&wm8903 2 0>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
pmc {
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
};
memory-controller@7000f400 {
status = "okay";
power-gpios = <&gpio 86 0>; /* gpio PK6 */
bus-width = <4>;
+ keep-power-in-suspend;
};
sdhci@c8000400 {
status = "okay";
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ cd-gpios = <&gpio 69 1>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 70 0>; /* gpio PI6 */
bus-width = <4>;
sdhci@c8000600 {
status = "okay";
bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
gpio-keys {
nvidia,spkr-en-gpios = <&wm8903 2 0>;
nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
pmc {
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
};
usb@c5008000 {
};
sdhci@c8000600 {
- cd-gpios = <&gpio 58 0>; /* gpio PH2 */
+ cd-gpios = <&gpio 58 1>; /* gpio PH2 */
wp-gpios = <&gpio 59 0>; /* gpio PH3 */
bus-width = <4>;
status = "okay";
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
regulators {
compatible = "simple-bus";
nvidia,spkr-en-gpios = <&wm8903 2 0>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
};
};
+ pmc {
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <5000>;
+ nvidia,cpu-pwr-off-time = <5000>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <3875>;
+ nvidia,sys-clock-req-active-high;
+ };
+
usb@c5000000 {
status = "okay";
nvidia,vbus-gpio = <&gpio 170 0>; /* gpio PV2 */
sdhci@c8000600 {
status = "okay";
- cd-gpios = <&gpio 121 0>; /* gpio PP1 */
+ cd-gpios = <&gpio 121 1>; /* gpio PP1 */
wp-gpios = <&gpio 122 0>; /* gpio PP2 */
bus-width = <4>;
};
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio 190 1>; /* gpio PX6, active low */
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
+ };
+
poweroff {
compatible = "gpio-poweroff";
gpios = <&gpio 191 1>; /* gpio PX7, active low */
compatible = "nvidia,tegra-audio-trimslice";
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&codec>;
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
pmc {
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <100>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <458>;
+ nvidia,sys-clock-req-active-high;
};
usb@c5000000 {
status = "okay";
power-gpios = <&gpio 86 0>; /* gpio PK6 */
bus-width = <4>;
+ keep-power-in-suspend;
};
sdhci@c8000400 {
status = "okay";
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ cd-gpios = <&gpio 69 1>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 70 0>; /* gpio PI6 */
bus-width = <4>;
sdhci@c8000600 {
status = "okay";
bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ gpios = <&gpio 170 1>; /* gpio PV2, active low */
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
};
regulators {
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */
nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
pmc {
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <1000>;
+ nvidia,core-pwr-good-time = <0 3845>;
+ nvidia,core-pwr-off-time = <93727>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ nvidia,combined-power-req;
};
usb@c5000000 {
sdhci@c8000400 {
status = "okay";
+ cd-gpios = <&gpio 69 1>; /* gpio PI5 */
wp-gpios = <&gpio 173 0>; /* gpio PV5 */
bus-width = <8>;
};
sdhci@c8000600 {
status = "okay";
bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
kbc {
nvidia,repeat-delay-ms = <160>;
nvidia,kbc-row-pins = <0 1 2>;
nvidia,kbc-col-pins = <16 17>;
+ nvidia,wakeup-source;
linux,keymap = <0x00000074 /* KEY_POWER */
0x01000066 /* KEY_HOME */
0x0101009E /* KEY_BACK */
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&codec>;
+
+ clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
0 1 0x04
0 41 0x04
0 42 0x04>;
+ clocks = <&tegra_car 5>;
};
tegra_car: clock {
compatible = "nvidia,tegra20-das";
reg = <0x70000c00 0x80>;
};
-
+
tegra_ac97: ac97 {
compatible = "nvidia,tegra20-ac97";
reg = <0x70002000 0x200>;
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car 17>;
+ status = "disabled";
};
rtc {
compatible = "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
+ clocks = <&tegra_car 4>;
};
i2c@7000c000 {
pmc {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car 110>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
};
memory-controller@7000f000 {
#size-cells = <0>;
};
- phy1: usb-phy@c5000400 {
- compatible = "nvidia,tegra20-usb-phy";
- reg = <0xc5000400 0x3c00>;
- phy_type = "utmi";
- nvidia,has-legacy-mode;
- clocks = <&tegra_car 22>, <&tegra_car 127>;
- clock-names = "phy", "pll_u";
- };
-
- phy2: usb-phy@c5004400 {
- compatible = "nvidia,tegra20-usb-phy";
- reg = <0xc5004400 0x3c00>;
- phy_type = "ulpi";
- clocks = <&tegra_car 94>, <&tegra_car 127>;
- clock-names = "phy", "pll_u";
- };
-
- phy3: usb-phy@c5008400 {
- compatible = "nvidia,tegra20-usb-phy";
- reg = <0xc5008400 0x3C00>;
- phy_type = "utmi";
- clocks = <&tegra_car 22>, <&tegra_car 127>;
- clock-names = "phy", "pll_u";
- };
-
usb@c5000000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5000000 0x4000>;
status = "disabled";
};
+ phy1: usb-phy@c5000400 {
+ compatible = "nvidia,tegra20-usb-phy";
+ reg = <0xc5000400 0x3c00>;
+ phy_type = "utmi";
+ nvidia,has-legacy-mode;
+ clocks = <&tegra_car 22>, <&tegra_car 127>;
+ clock-names = "phy", "pll_u";
+ };
+
usb@c5004000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5004000 0x4000>;
status = "disabled";
};
+ phy2: usb-phy@c5004400 {
+ compatible = "nvidia,tegra20-usb-phy";
+ reg = <0xc5004400 0x3c00>;
+ phy_type = "ulpi";
+ clocks = <&tegra_car 93>, <&tegra_car 127>;
+ clock-names = "phy", "pll_u";
+ };
+
usb@c5008000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5008000 0x4000>;
status = "disabled";
};
+ phy3: usb-phy@c5008400 {
+ compatible = "nvidia,tegra20-usb-phy";
+ reg = <0xc5008400 0x3c00>;
+ phy_type = "utmi";
+ clocks = <&tegra_car 22>, <&tegra_car 127>;
+ clock-names = "phy", "pll_u";
+ };
+
sdhci@c8000000 {
compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000000 0x200>;
pmc {
status = "okay";
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <200>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
};
sdhci@78000000 {
status = "okay";
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ cd-gpios = <&gpio 69 1>; /* gpio PI5 */
wp-gpios = <&gpio 155 0>; /* gpio PT3 */
power-gpios = <&gpio 31 0>; /* gpio PD7 */
bus-width = <4>;
sdhci@78000600 {
status = "okay";
bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
regulators {
status = "okay";
power-gpios = <&gpio 28 0>; /* gpio PD4 */
bus-width = <4>;
+ keep-power-in-suspend;
};
};
status = "okay";
power-gpios = <&gpio 27 0>; /* gpio PD3 */
bus-width = <4>;
+ keep-power-in-suspend;
};
};
pmc {
status = "okay";
nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <200>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
};
sdhci@78000000 {
status = "okay";
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ cd-gpios = <&gpio 69 1>; /* gpio PI5 */
wp-gpios = <&gpio 155 0>; /* gpio PT3 */
power-gpios = <&gpio 31 0>; /* gpio PD7 */
bus-width = <4>;
sdhci@78000600 {
status = "okay";
bus-width = <8>;
+ non-removable;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock {
+ compatible = "fixed-clock";
+ reg=<0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
regulators {
nvidia,spkr-en-gpios = <&wm8903 2 0>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+ clocks = <&tegra_car 184>, <&tegra_car 185>, <&tegra_car 120>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
};
};
0 42 0x04
0 121 0x04
0 122 0x04>;
+ clocks = <&tegra_car 5>;
};
tegra_car: clock {
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car 17>;
+ status = "disabled";
};
rtc {
compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
+ clocks = <&tegra_car 4>;
};
i2c@7000c000 {
};
pmc {
- compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+ compatible = "nvidia,tegra30-pmc";
reg = <0x7000e400 0x400>;
+ clocks = <&tegra_car 218>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
};
memory-controller {
--- /dev/null
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/tps65070.pdf
+ */
+
+&tps {
+ compatible = "ti,tps6507x";
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdcdc1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "VDCDC1";
+ };
+
+ vdcdc2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "VDCDC2";
+ };
+
+ vdcdc3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "VDCDC3";
+ };
+
+ ldo1_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "LDO1";
+ };
+
+ ldo2_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "LDO2";
+ };
+
+ };
+};
compatible = "ti,twl4030-wdt";
};
+ vcc: regulator-vdd1 {
+ compatible = "ti,twl4030-vdd1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1450000>;
+ };
+
vdac: regulator-vdac {
compatible = "ti,twl4030-vdac";
regulator-min-microvolt = <1800000>;
#interrupt-cells = <1>;
};
- twl4030-usb {
+ usb2_phy: twl4030-usb {
compatible = "ti,twl4030-usb";
interrupts = <10>, <4>;
usb1v5-supply = <&vusb1v5>;
usb3v1-supply = <&vusb3v1>;
usb_mode = <1>;
};
+
+ twl_pwm: pwm {
+ compatible = "ti,twl4030-pwm";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwmled: pwmled {
+ compatible = "ti,twl4030-pwmled";
+ #pwm-cells = <2>;
+ };
};
compatible = "ti,twl6030-usb";
interrupts = <4>, <10>;
};
+
+ twl_pwm: pwm {
+ /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */
+ compatible = "ti,twl6030-pwm";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwmled: pwmled {
+ /* provides one PWM (id 0 for Charging indicator LED) */
+ compatible = "ti,twl6030-pwmled";
+ #pwm-cells = <2>;
+ };
};
CONFIG_SPI=y
CONFIG_SPI_ORION=y
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_DOVE_THERMAL=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_SPI_ORION=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_KIRKWOOD_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
CONFIG_HID_DRAGONRISE=y
CONFIG_MTD=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_M25P80=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
CONFIG_SERIAL_8250_DW=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
+CONFIG_THERMAL=y
+CONFIG_ARMADA_THERMAL=y
CONFIG_USB_SUPPORT=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_RTC_DRV_MV=y
CONFIG_DMADEVICES=y
CONFIG_MV_XOR=y
+CONFIG_MEMORY=y
+CONFIG_MVEBU_DEVBUS=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
int twd_local_timer_register(struct twd_local_timer *);
-#ifdef CONFIG_HAVE_ARM_TWD
-void twd_local_timer_of_register(void);
-#else
-static inline void twd_local_timer_of_register(void)
-{
-}
-#endif
-
#endif
*/
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
-#define ARMADA_370_XP_REGS_VIRT_BASE 0xfeb00000
+#define ARMADA_370_XP_REGS_VIRT_BASE 0xfec00000
.macro addruart, rp, rv, tmp
ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE
}
#ifdef CONFIG_OF
-const static struct of_device_id twd_of_match[] __initconst = {
- { .compatible = "arm,cortex-a9-twd-timer", },
- { .compatible = "arm,cortex-a5-twd-timer", },
- { .compatible = "arm,arm11mp-twd-timer", },
- { },
-};
-
-void __init twd_local_timer_of_register(void)
+static void __init twd_local_timer_of_register(struct device_node *np)
{
- struct device_node *np;
int err;
if (!is_smp() || !setup_max_cpus)
return;
- np = of_find_matching_node(NULL, twd_of_match);
- if (!np)
- return;
-
twd_ppi = irq_of_parse_and_map(np, 0);
if (!twd_ppi) {
err = -EINVAL;
out:
WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
}
+CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register);
+CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register);
+CLOCKSOURCE_OF_DECLARE(arm_twd_11mp, "arm,arm11mp-twd-timer", twd_local_timer_of_register);
#endif
.wires = 8,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
- .version = MMC_CTLR_VERSION_2,
};
static inline void da830_evm_init_mmc(void)
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
- .version = MMC_CTLR_VERSION_2,
};
static const short da850_evm_mmcsd0_pins[] __initconst = {
.max_freq = 25000000,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE |
MMC_CAP_POWER_OFF_CARD,
- .version = MMC_CTLR_VERSION_2,
};
static const short da850_wl12xx_pins[] __initconst = {
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
- .version = MMC_CTLR_VERSION_1,
};
/* Don't connect anything to J10 unless you're only using USB host
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
- .version = MMC_CTLR_VERSION_2,
};
static void dm365evm_emac_configure(void)
.get_cd = dm6444evm_mmc_get_cd,
.get_ro = dm6444evm_mmc_get_ro,
.wires = 4,
- .version = MMC_CTLR_VERSION_1
};
static struct i2c_board_info __initdata i2c_info[] = {
static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
.wires = 4,
- .version = MMC_CTLR_VERSION_1
};
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
- .version = MMC_CTLR_VERSION_2,
};
static __init void omapl138_hawk_mmc_init(void)
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
- .version = MMC_CTLR_VERSION_1,
};
static const short sdio1_pins[] __initconst = {
{
if (clk->parent)
__clk_enable(clk->parent);
- if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- true, clk->flags);
+ if (clk->usecount++ == 0) {
+ if (clk->flags & CLK_PSC)
+ davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
+ true, clk->flags);
+ else if (clk->clk_enable)
+ clk->clk_enable(clk);
+ }
}
static void __clk_disable(struct clk *clk)
{
if (WARN_ON(clk->usecount == 0))
return;
- if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
- (clk->flags & CLK_PSC))
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- false, clk->flags);
+ if (--clk->usecount == 0) {
+ if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
+ davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
+ false, clk->flags);
+ else if (clk->clk_disable)
+ clk->clk_disable(clk);
+ }
if (clk->parent)
__clk_disable(clk->parent);
}
int (*set_rate) (struct clk *clk, unsigned long rate);
int (*round_rate) (struct clk *clk, unsigned long rate);
int (*reset) (struct clk *clk, bool reset);
+ void (*clk_enable) (struct clk *clk);
+ void (*clk_disable) (struct clk *clk);
};
/* Clock flags: SoC-specific flags start at BIT(16) */
CLK(NULL, "tpcc", &tpcc_clk),
CLK(NULL, "tptc0", &tptc0_clk),
CLK(NULL, "tptc1", &tptc1_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK("da830-mmc.0", NULL, &mmcsd_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
.flags = PSC_LRST | PSC_FORCE,
};
+static struct clk ehrpwm_clk = {
+ .name = "ehrpwm",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
+
+static void ehrpwm_tblck_enable(struct clk *clk)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+ val |= DA8XX_EHRPWM_TBCLKSYNC;
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+}
+
+static void ehrpwm_tblck_disable(struct clk *clk)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+ val &= ~DA8XX_EHRPWM_TBCLKSYNC;
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
+}
+
+static struct clk ehrpwm_tbclk = {
+ .name = "ehrpwm_tbclk",
+ .parent = &ehrpwm_clk,
+ .clk_enable = ehrpwm_tblck_enable,
+ .clk_disable = ehrpwm_tblck_disable,
+};
+
+static struct clk ecap_clk = {
+ .name = "ecap",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
static struct clk_lookup da850_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll0", &pll0_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("davinci-mcasp.0", NULL, &mcasp_clk),
CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
- CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("da830-mmc.0", NULL, &mmcsd0_clk),
+ CLK("da830-mmc.1", NULL, &mmcsd1_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "usb11", &usb11_clk),
CLK(NULL, "usb20", &usb20_clk),
CLK("vpif", NULL, &vpif_clk),
CLK("ahci", NULL, &sata_clk),
CLK("davinci-rproc.0", NULL, &dsp_clk),
+ CLK("ehrpwm", "fck", &ehrpwm_clk),
+ CLK("ehrpwm", "tbclk", &ehrpwm_tbclk),
+ CLK("ecap", "fck", &ecap_clk),
CLK(NULL, NULL, NULL),
};
struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "watchdog", NULL),
+ OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
+ OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL),
+ OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
{}
};
};
static struct platform_device da8xx_mmcsd0_device = {
- .name = "davinci_mmc",
+ .name = "da830-mmc",
.id = 0,
.num_resources = ARRAY_SIZE(da8xx_mmcsd0_resources),
.resource = da8xx_mmcsd0_resources,
};
static struct platform_device da850_mmcsd1_device = {
- .name = "davinci_mmc",
+ .name = "da830-mmc",
.id = 1,
.num_resources = ARRAY_SIZE(da850_mmcsd1_resources),
.resource = da850_mmcsd1_resources,
static struct platform_device mmc_devices[2] = {
{
- .name = "davinci_mmc",
+ .name = "dm6441-mmc",
.id = 0,
.dev = {
.dma_mask = &mmc0_dma_mask,
.resource = mmc0_resources
},
{
- .name = "davinci_mmc",
+ .name = "dm6441-mmc",
.id = 1,
.dev = {
.dma_mask = &mmc1_dma_mask,
};
static struct platform_device davinci_mmcsd0_device = {
- .name = "davinci_mmc",
+ .name = "dm6441-mmc",
.id = 0,
.dev = {
.dma_mask = &mmcsd0_dma_mask,
};
static struct platform_device davinci_mmcsd1_device = {
- .name = "davinci_mmc",
+ .name = "dm6441-mmc",
.id = 1,
.dev = {
.dma_mask = &mmcsd1_dma_mask,
mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
SZ_4K - 1;
mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
+ davinci_mmcsd1_device.name = "da830-mmc";
} else
break;
mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
SZ_4K - 1;
mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
+ davinci_mmcsd0_device.name = "da830-mmc";
} else if (cpu_is_davinci_dm644x()) {
/* REVISIT: should this be in board-init code? */
/* Power-on 3.3V IO cells */
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("davinci-mcbsp.0", NULL, &asp0_clk),
CLK("davinci-mcbsp.1", NULL, &asp1_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
- CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
+ CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
CLK("spi_davinci.0", NULL, &spi0_clk),
CLK("spi_davinci.1", NULL, &spi1_clk),
CLK("spi_davinci.2", NULL, &spi2_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
- CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("da830-mmc.0", NULL, &mmcsd0_clk),
+ CLK("da830-mmc.1", NULL, &mmcsd1_clk),
CLK("spi_davinci.0", NULL, &spi0_clk),
CLK("spi_davinci.1", NULL, &spi1_clk),
CLK("spi_davinci.2", NULL, &spi2_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("palm_bk3710", NULL, &ide_clk),
CLK("davinci-mcbsp", NULL, &asp_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
CLK(NULL, "spi", &spi_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK(NULL, "usb", &usb_clk),
#define DA8XX_SYSCFG0_VIRT(x) (da8xx_syscfg0_base + (x))
#define DA8XX_JTAG_ID_REG 0x18
#define DA8XX_CFGCHIP0_REG 0x17c
+#define DA8XX_CFGCHIP1_REG 0x180
#define DA8XX_CFGCHIP2_REG 0x184
#define DA8XX_CFGCHIP3_REG 0x188
#if defined(CONFIG_DEBUG_DAVINCI_DMx_UART0)
#define UART_BASE DAVINCI_UART0_BASE
-#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART0)
-#define UART_BASE DA8XX_UART0_BASE
#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART1)
#define UART_BASE DA8XX_UART1_BASE
#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART2)
CLK("tnetv107x-keypad.0", NULL, &clk_keypad),
CLK(NULL, "clk_gpio", &clk_gpio),
CLK(NULL, "clk_mdio", &clk_mdio),
- CLK("davinci_mmc.0", NULL, &clk_sdio0),
+ CLK("dm6441-mmc.0", NULL, &clk_sdio0),
CLK(NULL, "uart0", &clk_uart0),
CLK(NULL, "uart1", &clk_uart1),
CLK(NULL, "timer0", &clk_timer0),
CLK(NULL, "clk_system", &clk_system),
CLK(NULL, "clk_imcop", &clk_imcop),
CLK(NULL, "clk_spare", &clk_spare),
- CLK("davinci_mmc.1", NULL, &clk_sdio1),
+ CLK("dm6441-mmc.1", NULL, &clk_sdio1),
CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst),
CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst),
CLK(NULL, NULL, NULL),
-obj-y += common.o addr-map.o irq.o
+obj-y += common.o irq.o
obj-$(CONFIG_DOVE_LEGACY) += mpp.o
obj-$(CONFIG_PCI) += pcie.o
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
+++ /dev/null
-/*
- * arch/arm/mach-dove/addr-map.c
- *
- * Address map functions for Marvell Dove 88AP510 SoC
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <asm/mach/arch.h>
-#include <asm/setup.h>
-#include <mach/dove.h>
-#include <plat/addr-map.h>
-#include "common.h"
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DDR 0x0
-#define TARGET_BOOTROM 0x1
-#define TARGET_CESA 0x3
-#define TARGET_PCIE0 0x4
-#define TARGET_PCIE1 0x8
-#define TARGET_SCRATCHPAD 0xd
-
-#define ATTR_CESA 0x01
-#define ATTR_BOOTROM 0xfd
-#define ATTR_DEV_SPI0_ROM 0xfe
-#define ATTR_DEV_SPI1_ROM 0xfb
-#define ATTR_PCIE_IO 0xe0
-#define ATTR_PCIE_MEM 0xe8
-#define ATTR_SCRATCHPAD 0x0
-
-static inline void __iomem *ddr_map_sc(int i)
-{
- return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
-}
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
- .num_wins = 8,
- .remappable_wins = 4,
- .bridge_virt_base = BRIDGE_VIRT_BASE,
-};
-
-static const struct __initdata orion_addr_map_info addr_map_info[] = {
- /*
- * Windows for PCIe IO+MEM space.
- */
- { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
- TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE
- },
- { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
- TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE
- },
- { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
- TARGET_PCIE0, ATTR_PCIE_MEM, -1
- },
- { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
- TARGET_PCIE1, ATTR_PCIE_MEM, -1
- },
- /*
- * Window for CESA engine.
- */
- { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
- TARGET_CESA, ATTR_CESA, -1
- },
- /*
- * Window to the BootROM for Standby and Sleep Resume
- */
- { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
- TARGET_BOOTROM, ATTR_BOOTROM, -1
- },
- /*
- * Window to the PMU Scratch Pad space
- */
- { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
- TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1
- },
- /* End marker */
- { -1, 0, 0, 0, 0, 0 }
-};
-
-void __init dove_setup_cpu_mbus(void)
-{
- int i;
- int cs;
-
- /*
- * Disable, clear and configure windows.
- */
- orion_config_wins(&addr_map_cfg, addr_map_info);
-
- /*
- * Setup MBUS dram target info.
- */
- orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
-
- for (i = 0, cs = 0; i < 2; i++) {
- u32 map = readl(ddr_map_sc(i));
-
- /*
- * Chip select enabled?
- */
- if (map & 1) {
- struct mbus_dram_window *w;
-
- w = &orion_mbus_dram_info.cs[cs++];
- w->cs_index = i;
- w->mbus_attr = 0; /* CS address decoding done inside */
- /* the DDR controller, no need to */
- /* provide attributes */
- w->base = map & 0xff800000;
- w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
- }
- }
- orion_mbus_dram_info.num_cs = cs;
-}
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
#endif
- dove_setup_cpu_mbus();
+ dove_setup_cpu_wins();
/* Setup root of clk tree */
dove_of_clk_init();
void __init dove_init_early(void)
{
orion_time_set_base(TIMER_VIRT_BASE);
+ mvebu_mbus_init("marvell,dove-mbus",
+ BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
+ DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
}
static int __init dove_find_tclk(void)
platform_device_register(&dove_sdio1);
}
+void __init dove_setup_cpu_wins(void)
+{
+ /*
+ * The PCIe windows will no longer be statically allocated
+ * here once Dove is migrated to the pci-mvebu driver.
+ */
+ mvebu_mbus_add_window_remap_flags("pcie0.0",
+ DOVE_PCIE0_IO_PHYS_BASE,
+ DOVE_PCIE0_IO_SIZE,
+ DOVE_PCIE0_IO_BUS_BASE,
+ MVEBU_MBUS_PCI_IO);
+ mvebu_mbus_add_window_remap_flags("pcie1.0",
+ DOVE_PCIE1_IO_PHYS_BASE,
+ DOVE_PCIE1_IO_SIZE,
+ DOVE_PCIE1_IO_BUS_BASE,
+ MVEBU_MBUS_PCI_IO);
+ mvebu_mbus_add_window_remap_flags("pcie0.0",
+ DOVE_PCIE0_MEM_PHYS_BASE,
+ DOVE_PCIE0_MEM_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
+ mvebu_mbus_add_window_remap_flags("pcie1.0",
+ DOVE_PCIE1_MEM_PHYS_BASE,
+ DOVE_PCIE1_MEM_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
+ mvebu_mbus_add_window("cesa", DOVE_CESA_PHYS_BASE,
+ DOVE_CESA_SIZE);
+ mvebu_mbus_add_window("bootrom", DOVE_BOOTROM_PHYS_BASE,
+ DOVE_BOOTROM_SIZE);
+ mvebu_mbus_add_window("scratchpad", DOVE_SCRATCHPAD_PHYS_BASE,
+ DOVE_SCRATCHPAD_SIZE);
+}
+
void __init dove_init(void)
{
pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
#endif
- dove_setup_cpu_mbus();
+ dove_setup_cpu_wins();
/* Setup root of clk tree */
dove_clk_init();
void dove_init(void);
void dove_init_early(void);
void dove_init_irq(void);
-void dove_setup_cpu_mbus(void);
+void dove_setup_cpu_wins(void);
void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void dove_sata_init(struct mv_sata_platform_data *sata_data);
#ifdef CONFIG_PCI
/* North-South Bridge */
#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x20000)
#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000)
+#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
+#define BRIDGE_WINS_SZ (0x80)
/* Cryptographic Engine */
#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x30000)
#define DOVE_SSP_CLOCK_ENABLE (1 << 1)
#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11)
/* Memory Controller */
+#define DOVE_MC_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x00000)
+#define DOVE_MC_WINS_BASE (DOVE_MC_PHYS_BASE + 0x100)
+#define DOVE_MC_WINS_SZ (0x8)
#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE + 0x00000)
/* LCD Controller */
#include <asm/cacheflush.h>
#include <asm/cputype.h>
#include <asm/smp_plat.h>
-#include <asm/smp_twd.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/timer-sp.h>
#include <asm/hardware/cache-l2x0.h>
sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
sp804_clockevents_init(timer_base, irq, "timer0");
- twd_local_timer_of_register();
-
arch_timer_of_register();
arch_timer_sched_clock_init();
+
+ clocksource_of_init();
}
static void highbank_power_off(void)
busy->mux.reg = reg;
busy->mux.shift = shift;
- busy->mux.width = width;
+ busy->mux.mask = BIT(width) - 1;
busy->mux.lock = &imx_ccm_lock;
busy->mux_ops = &clk_mux_ops;
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/clocksource.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/regmap.h>
#include <linux/micrel_phy.h>
#include <linux/mfd/syscon.h>
-#include <asm/smp_twd.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <asm/mach/time.h>
#include <asm/system_misc.h>
#include "common.h"
static void __init imx6q_timer_init(void)
{
mx6q_clocks_init();
- twd_local_timer_of_register();
+ clocksource_of_init();
imx_print_silicon_rev("i.MX6Q", imx6q_revision());
}
-obj-y += common.o addr-map.o irq.o pcie.o mpp.o
+obj-y += common.o irq.o pcie.o mpp.o
obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
+++ /dev/null
-/*
- * arch/arm/mach-kirkwood/addr-map.c
- *
- * Address map functions for Marvell Kirkwood SoCs
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <plat/addr-map.h>
-#include "common.h"
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DEV_BUS 1
-#define TARGET_SRAM 3
-#define TARGET_PCIE 4
-#define ATTR_DEV_SPI_ROM 0x1e
-#define ATTR_DEV_BOOT 0x1d
-#define ATTR_DEV_NAND 0x2f
-#define ATTR_DEV_CS3 0x37
-#define ATTR_DEV_CS2 0x3b
-#define ATTR_DEV_CS1 0x3d
-#define ATTR_DEV_CS0 0x3e
-#define ATTR_PCIE_IO 0xe0
-#define ATTR_PCIE_MEM 0xe8
-#define ATTR_PCIE1_IO 0xd0
-#define ATTR_PCIE1_MEM 0xd8
-#define ATTR_SRAM 0x01
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
- .num_wins = 8,
- .remappable_wins = 4,
- .bridge_virt_base = BRIDGE_VIRT_BASE,
-};
-
-static const struct __initdata orion_addr_map_info addr_map_info[] = {
- /*
- * Windows for PCIe IO+MEM space.
- */
- { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
- TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE
- },
- { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
- TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE
- },
- { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
- TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE
- },
- { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
- TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE
- },
- /*
- * Window for NAND controller.
- */
- { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
- TARGET_DEV_BUS, ATTR_DEV_NAND, -1
- },
- /*
- * Window for SRAM.
- */
- { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
- TARGET_SRAM, ATTR_SRAM, -1
- },
- /* End marker */
- { -1, 0, 0, 0, 0, 0 }
-};
-
-void __init kirkwood_setup_cpu_mbus(void)
-{
- /*
- * Disable, clear and configure windows.
- */
- orion_config_wins(&addr_map_cfg, addr_map_info);
-
- /*
- * Setup MBUS dram target info.
- */
- orion_setup_cpu_mbus_target(&addr_map_cfg,
- (void __iomem *) DDR_WINDOW_CPU_BASE);
-}
*/
writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
- kirkwood_setup_cpu_mbus();
+ kirkwood_setup_wins();
kirkwood_l2_init();
#include <linux/init.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
-#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
static struct mv643xx_eth_platform_data guruplug_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(1),
};
-static struct mvsdio_platform_data guruplug_mvsdio_data = {
- /* unfortunately the CD signal has not been connected */
-};
-
void __init guruplug_dt_init(void)
{
/*
*/
kirkwood_ge00_init(&guruplug_ge00_data);
kirkwood_ge01_init(&guruplug_ge01_data);
- kirkwood_sdio_init(&guruplug_mvsdio_data);
}
#include <linux/platform_data/usb-ehci-orion.h>
#include <plat/common.h>
#include <plat/time.h>
-#include <plat/addr-map.h>
#include <linux/platform_data/dma-mv_xor.h>
#include "common.h"
* the allocations won't fail.
*/
init_dma_coherent_pool_size(SZ_1M);
+ mvebu_mbus_init("marvell,kirkwood-mbus",
+ BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
+ DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
}
int kirkwood_tclk;
}
}
+void __init kirkwood_setup_wins(void)
+{
+ /*
+ * The PCIe windows will no longer be statically allocated
+ * here once Kirkwood is migrated to the pci-mvebu driver.
+ */
+ mvebu_mbus_add_window_remap_flags("pcie0.0",
+ KIRKWOOD_PCIE_IO_PHYS_BASE,
+ KIRKWOOD_PCIE_IO_SIZE,
+ KIRKWOOD_PCIE_IO_BUS_BASE,
+ MVEBU_MBUS_PCI_IO);
+ mvebu_mbus_add_window_remap_flags("pcie0.0",
+ KIRKWOOD_PCIE_MEM_PHYS_BASE,
+ KIRKWOOD_PCIE_MEM_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
+ mvebu_mbus_add_window_remap_flags("pcie1.0",
+ KIRKWOOD_PCIE1_IO_PHYS_BASE,
+ KIRKWOOD_PCIE1_IO_SIZE,
+ KIRKWOOD_PCIE1_IO_BUS_BASE,
+ MVEBU_MBUS_PCI_IO);
+ mvebu_mbus_add_window_remap_flags("pcie1.0",
+ KIRKWOOD_PCIE1_MEM_PHYS_BASE,
+ KIRKWOOD_PCIE1_MEM_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
+ mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE,
+ KIRKWOOD_NAND_MEM_SIZE);
+ mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE,
+ KIRKWOOD_SRAM_SIZE);
+}
+
void __init kirkwood_l2_init(void)
{
#ifdef CONFIG_CACHE_FEROCEON_L2
*/
writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
- kirkwood_setup_cpu_mbus();
+ kirkwood_setup_wins();
kirkwood_l2_init();
void kirkwood_init_early(void);
void kirkwood_init_irq(void);
-void kirkwood_setup_cpu_mbus(void);
+void kirkwood_setup_wins(void);
void kirkwood_enable_pcie(void);
void kirkwood_pcie_id(u32 *dev, u32 *rev);
* Register Map
*/
#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000)
-#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
-#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500)
+#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
+#define DDR_WINDOW_CPU_BASE (DDR_PHYS_BASE + 0x1500)
+#define DDR_WINDOW_CPU_SZ (0x20)
#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418)
#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000)
#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000)
#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
+#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
+#define BRIDGE_WINS_SZ (0x80)
#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000)
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include <mach/bridge-regs.h>
-#include <plat/addr-map.h>
#include "common.h"
static void kirkwood_enable_pcie_clk(const char *port)
-obj-y += common.o addr-map.o mpp.o irq.o pcie.o
+obj-y += common.o mpp.o irq.o pcie.o
obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o
obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o
obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
+++ /dev/null
-/*
- * arch/arm/mach-mv78xx0/addr-map.c
- *
- * Address map functions for Marvell MV78xx0 SoCs
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <plat/addr-map.h>
-#include <mach/mv78xx0.h>
-#include "common.h"
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DEV_BUS 1
-#define TARGET_PCIE0 4
-#define TARGET_PCIE1 8
-#define TARGET_PCIE(i) ((i) ? TARGET_PCIE1 : TARGET_PCIE0)
-#define ATTR_DEV_SPI_ROM 0x1f
-#define ATTR_DEV_BOOT 0x2f
-#define ATTR_DEV_CS3 0x37
-#define ATTR_DEV_CS2 0x3b
-#define ATTR_DEV_CS1 0x3d
-#define ATTR_DEV_CS0 0x3e
-#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l)))
-#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l)))
-
-/*
- * CPU Address Decode Windows registers
- */
-#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
-#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
-
-static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
-{
- /*
- * Find the control register base address for this window.
- *
- * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's)
- * MBUS bridge depending on which CPU core we're running on,
- * so we don't need to take that into account here.
- */
-
- return (win < 8) ? WIN0_OFF(win) : WIN8_OFF(win);
-}
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct orion_addr_map_cfg addr_map_cfg __initdata = {
- .num_wins = 14,
- .remappable_wins = 8,
- .win_cfg_base = win_cfg_base,
-};
-
-void __init mv78xx0_setup_cpu_mbus(void)
-{
- /*
- * Disable, clear and configure windows.
- */
- orion_config_wins(&addr_map_cfg, NULL);
-
- /*
- * Setup MBUS dram target info.
- */
- if (mv78xx0_core_index() == 0)
- orion_setup_cpu_mbus_target(&addr_map_cfg,
- (void __iomem *) DDR_WINDOW_CPU0_BASE);
- else
- orion_setup_cpu_mbus_target(&addr_map_cfg,
- (void __iomem *) DDR_WINDOW_CPU1_BASE);
-}
-
-void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
- int maj, int min)
-{
- orion_setup_cpu_win(&addr_map_cfg, window, base, size,
- TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0);
-}
-
-void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
- int maj, int min)
-{
- orion_setup_cpu_win(&addr_map_cfg, window, base, size,
- TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1);
-}
void __init mv78xx0_init_early(void)
{
orion_time_set_base(TIMER_VIRT_BASE);
+ if (mv78xx0_core_index() == 0)
+ mvebu_mbus_init("marvell,mv78xx0-mbus",
+ BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
+ DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
+ else
+ mvebu_mbus_init("marvell,mv78xx0-mbus",
+ BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
+ DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
}
void __init_refok mv78xx0_timer_init(void)
printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
- mv78xx0_setup_cpu_mbus();
-
#ifdef CONFIG_CACHE_FEROCEON_L2
feroceon_l2_init(is_l2_writethrough());
#endif
*/
#define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE)
#define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE)
+#define BRIDGE_WINS_CPU0_BASE (MV78XX0_CORE0_REGS_PHYS_BASE)
+#define BRIDGE_WINS_CPU1_BASE (MV78XX0_CORE1_REGS_PHYS_BASE)
+#define BRIDGE_WINS_SZ (0xA000)
/*
* Register Map
*/
#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000)
-#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE + 0x1500)
-#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE + 0x1570)
+#define DDR_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x00000)
+#define DDR_WINDOW_CPU0_BASE (DDR_PHYS_BASE + 0x1500)
+#define DDR_WINDOW_CPU1_BASE (DDR_PHYS_BASE + 0x1570)
+#define DDR_WINDOW_CPU_SZ (0x20)
#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x10000)
#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x10000)
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/mbus.h>
#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
-#include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h"
int i;
u32 size_each;
u32 start;
- int win = 0;
pcie_io_space.name = "PCIe I/O Space";
pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
start = MV78XX0_PCIE_MEM_PHYS_BASE;
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
+ char winname[MVEBU_MBUS_MAX_WINNAME_SZ];
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d.%d MEM", pp->maj, pp->min);
if (request_resource(&iomem_resource, &pp->res))
panic("can't allocate PCIe MEM sub-space");
- mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start,
- resource_size(&pp->res),
- pp->maj, pp->min);
-
- mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K,
- pp->maj, pp->min);
+ snprintf(winname, sizeof(winname), "pcie%d.%d",
+ pp->maj, pp->min);
+
+ mvebu_mbus_add_window_remap_flags(winname,
+ pp->res.start,
+ resource_size(&pp->res),
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
+ mvebu_mbus_add_window_remap_flags(winname,
+ i * SZ_64K, SZ_64K,
+ 0, MVEBU_MBUS_PCI_IO);
}
}
select MVEBU_CLK_CORE
select MVEBU_CLK_CPU
select MVEBU_CLK_GATING
+ select MVEBU_MBUS
+ select ZONE_DMA if ARM_LPAE
if ARCH_MVEBU
obj-y += system-controller.o
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o
-obj-$(CONFIG_ARCH_MVEBU) += addr-map.o coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o
+obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+++ /dev/null
-/*
- * Address map functions for Marvell 370 / XP SoCs
- *
- * Copyright (C) 2012 Marvell
- *
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <plat/addr-map.h>
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define ARMADA_XP_TARGET_DEV_BUS 1
-#define ARMADA_XP_ATTR_DEV_BOOTROM 0x1D
-#define ARMADA_XP_TARGET_ETH1 3
-#define ARMADA_XP_TARGET_PCIE_0_2 4
-#define ARMADA_XP_TARGET_ETH0 7
-#define ARMADA_XP_TARGET_PCIE_1_3 8
-
-#define ARMADA_370_TARGET_DEV_BUS 1
-#define ARMADA_370_ATTR_DEV_BOOTROM 0x1D
-#define ARMADA_370_TARGET_PCIE_0 4
-#define ARMADA_370_TARGET_PCIE_1 8
-
-#define ARMADA_WINDOW_8_PLUS_OFFSET 0x90
-#define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180
-
-static const struct __initdata orion_addr_map_info
-armada_xp_addr_map_info[] = {
- /*
- * Window for the BootROM, needed for SMP on Armada XP
- */
- { 0, 0xfff00000, SZ_1M, ARMADA_XP_TARGET_DEV_BUS,
- ARMADA_XP_ATTR_DEV_BOOTROM, -1 },
- /* End marker */
- { -1, 0, 0, 0, 0, 0 },
-};
-
-static const struct __initdata orion_addr_map_info
-armada_370_addr_map_info[] = {
- /* End marker */
- { -1, 0, 0, 0, 0, 0 },
-};
-
-static struct of_device_id of_addr_decoding_controller_table[] = {
- { .compatible = "marvell,armada-addr-decoding-controller" },
- { /* end of list */ },
-};
-
-static void __iomem *
-armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
-{
- unsigned int offset;
-
- /* The register layout is a bit annoying and the below code
- * tries to cope with it.
- * - At offset 0x0, there are the registers for the first 8
- * windows, with 4 registers of 32 bits per window (ctrl,
- * base, remap low, remap high)
- * - Then at offset 0x80, there is a hole of 0x10 bytes for
- * the internal registers base address and internal units
- * sync barrier register.
- * - Then at offset 0x90, there the registers for 12
- * windows, with only 2 registers of 32 bits per window
- * (ctrl, base).
- */
- if (win < 8)
- offset = (win << 4);
- else
- offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3);
-
- return cfg->bridge_virt_base + offset;
-}
-
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
- .num_wins = 20,
- .remappable_wins = 8,
- .win_cfg_base = armada_cfg_base,
-};
-
-static int __init armada_setup_cpu_mbus(void)
-{
- struct device_node *np;
- void __iomem *mbus_unit_addr_decoding_base;
- void __iomem *sdram_addr_decoding_base;
-
- np = of_find_matching_node(NULL, of_addr_decoding_controller_table);
- if (!np)
- return -ENODEV;
-
- mbus_unit_addr_decoding_base = of_iomap(np, 0);
- BUG_ON(!mbus_unit_addr_decoding_base);
-
- sdram_addr_decoding_base =
- mbus_unit_addr_decoding_base +
- ARMADA_SDRAM_ADDR_DECODING_OFFSET;
-
- addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;
-
- if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
- addr_map_cfg.hw_io_coherency = 1;
-
- /*
- * Disable, clear and configure windows.
- */
- if (of_machine_is_compatible("marvell,armadaxp"))
- orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info);
- else if (of_machine_is_compatible("marvell,armada370"))
- orion_config_wins(&addr_map_cfg, armada_370_addr_map_info);
- else {
- pr_err("Unsupported SoC\n");
- return -EINVAL;
- }
-
- /*
- * Setup MBUS dram target info.
- */
- orion_setup_cpu_mbus_target(&addr_map_cfg,
- sdram_addr_decoding_base);
- return 0;
-}
-
-/* Using a early_initcall is needed so that this initialization gets
- * done before the SMP initialization, which requires the BootROM to
- * be remapped. */
-early_initcall(armada_setup_cpu_mbus);
#include <linux/time-armada-370-xp.h>
#include <linux/clk/mvebu.h>
#include <linux/dma-mapping.h>
+#include <linux/mbus.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
void __init armada_370_xp_init_early(void)
{
+ char *mbus_soc_name;
+
/*
* Some Armada 370/XP devices allocate their coherent buffers
* from atomic context. Increase size of atomic coherent pool
* to make sure such the allocations won't fail.
*/
init_dma_coherent_pool_size(SZ_1M);
+
+ /*
+ * This initialization will be replaced by a DT-based
+ * initialization once the mvebu-mbus driver gains DT support.
+ */
+ if (of_machine_is_compatible("marvell,armada370"))
+ mbus_soc_name = "marvell,armada370-mbus";
+ else
+ mbus_soc_name = "marvell,armadaxp-mbus";
+
+ mvebu_mbus_init(mbus_soc_name,
+ ARMADA_370_XP_MBUS_WINS_BASE,
+ ARMADA_370_XP_MBUS_WINS_SIZE,
+ ARMADA_370_XP_SDRAM_WINS_BASE,
+ ARMADA_370_XP_SDRAM_WINS_SIZE);
}
static void __init armada_370_xp_dt_init(void)
#define __MACH_ARMADA_370_XP_H
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
-#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000)
+#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfec00000)
#define ARMADA_370_XP_REGS_SIZE SZ_1M
+/* These defines can go away once mvebu-mbus has a DT binding */
+#define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
+#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100
+#define ARMADA_370_XP_SDRAM_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180)
+#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20
+
#ifdef CONFIG_SMP
#include <linux/cpumask.h>
#include <linux/smp.h>
#include <linux/clk.h>
#include <linux/of.h>
+#include <linux/mbus.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include "common.h"
set_secondary_cpus_clock();
flush_cache_all();
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
+ mvebu_mbus_add_window("bootrom", 0xfff00000, SZ_1M);
}
struct smp_operations armada_xp_smp_ops __initdata = {
-# Common support
-obj-y := icoll.o ocotp.o system.o timer.o mm.o
-
obj-$(CONFIG_PM) += pm.o
-
obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
+++ /dev/null
-/*
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <asm/exception.h>
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-#define HW_ICOLL_VECTOR 0x0000
-#define HW_ICOLL_LEVELACK 0x0010
-#define HW_ICOLL_CTRL 0x0020
-#define HW_ICOLL_STAT_OFFSET 0x0070
-#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
-#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
-#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
-#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
-
-#define ICOLL_NUM_IRQS 128
-
-static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
-static struct irq_domain *icoll_domain;
-
-static void icoll_ack_irq(struct irq_data *d)
-{
- /*
- * The Interrupt Collector is able to prioritize irqs.
- * Currently only level 0 is used. So acking can use
- * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
- */
- __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
- icoll_base + HW_ICOLL_LEVELACK);
-}
-
-static void icoll_mask_irq(struct irq_data *d)
-{
- __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
- icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
-}
-
-static void icoll_unmask_irq(struct irq_data *d)
-{
- __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
- icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
-}
-
-static struct irq_chip mxs_icoll_chip = {
- .irq_ack = icoll_ack_irq,
- .irq_mask = icoll_mask_irq,
- .irq_unmask = icoll_unmask_irq,
-};
-
-asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
-{
- u32 irqnr;
-
- do {
- irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
- if (irqnr != 0x7f) {
- __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
- irqnr = irq_find_mapping(icoll_domain, irqnr);
- handle_IRQ(irqnr, regs);
- continue;
- }
- break;
- } while (1);
-}
-
-static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
- irq_hw_number_t hw)
-{
- irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
- set_irq_flags(virq, IRQF_VALID);
-
- return 0;
-}
-
-static struct irq_domain_ops icoll_irq_domain_ops = {
- .map = icoll_irq_domain_map,
- .xlate = irq_domain_xlate_onecell,
-};
-
-static void __init icoll_of_init(struct device_node *np,
- struct device_node *interrupt_parent)
-{
- /*
- * Interrupt Collector reset, which initializes the priority
- * for each irq to level 0.
- */
- mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
-
- icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
- &icoll_irq_domain_ops, NULL);
- WARN_ON(!icoll_domain);
-}
-
-static const struct of_device_id icoll_of_match[] __initconst = {
- {.compatible = "fsl,icoll", .data = icoll_of_init},
- { /* sentinel */ }
-};
-
-void __init icoll_init_irq(void)
-{
- of_irq_init(icoll_of_match);
-}
+++ /dev/null
-/*
- * Copyright 2004-2007 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 version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __MACH_MXS_COMMON_H__
-#define __MACH_MXS_COMMON_H__
-
-extern const u32 *mxs_get_ocotp(void);
-extern int mxs_reset_block(void __iomem *);
-extern void mxs_timer_init(void);
-extern void mxs_restart(char, const char *);
-extern int mxs_saif_clkmux_select(unsigned int clkmux);
-
-extern int mx23_clocks_init(void);
-extern void mx23_map_io(void);
-
-extern int mx28_clocks_init(void);
-extern void mx28_map_io(void);
-
-extern void icoll_init_irq(void);
-extern void icoll_handle_irq(struct pt_regs *);
-
-#endif /* __MACH_MXS_COMMON_H__ */
*
*/
-#include <mach/mx23.h>
-#include <mach/mx28.h>
-
#ifdef CONFIG_DEBUG_IMX23_UART
-#define UART_PADDR MX23_DUART_BASE_ADDR
+#define UART_PADDR 0x80070000
#elif defined (CONFIG_DEBUG_IMX28_UART)
-#define UART_PADDR MX28_DUART_BASE_ADDR
+#define UART_PADDR 0x80074000
#endif
-#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
+#define UART_VADDR 0xfe100000
.macro addruart, rp, rv, tmp
ldr \rp, =UART_PADDR @ physical
+++ /dev/null
-/*
- * Copyright 2011 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 version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __MACH_DIGCTL_H__
-#define __MACH_DIGCTL_H__
-
-/* MXS DIGCTL SAIF CLKMUX */
-#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0
-#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1
-#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2
-#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3
-
-#define HW_DIGCTL_CTRL 0x0
-#define BP_DIGCTL_CTRL_SAIF_CLKMUX 10
-#define BM_DIGCTL_CTRL_SAIF_CLKMUX (0x3 << 10)
-#define HW_DIGCTL_CHIPID 0x310
-#endif
+++ /dev/null
-/*
- * Copyright 2004-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_HARDWARE_H__
-#define __MACH_MXS_HARDWARE_H__
-
-#endif /* __MACH_MXS_HARDWARE_H__ */
+++ /dev/null
-/*
- * 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.
- */
-
-#ifndef __MACH_MX23_H__
-#define __MACH_MX23_H__
-
-#include <mach/mxs.h>
-
-/*
- * OCRAM
- */
-#define MX23_OCRAM_BASE_ADDR 0x00000000
-#define MX23_OCRAM_SIZE SZ_32K
-
-/*
- * IO
- */
-#define MX23_IO_BASE_ADDR 0x80000000
-#define MX23_IO_SIZE SZ_1M
-
-#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
-#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
-#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
-#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
-#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
-#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
-#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
-#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
-#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
-#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
-#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
-#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
-#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
-#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
-#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
-#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
-#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
-#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
-#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
-#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
-#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
-#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
-#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
-#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
-#define MX23_I2C_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
-#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
-#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
-#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
-#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
-#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
-#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
-#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
-#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
-#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
-
-#define MX23_IO_P2V(x) MXS_IO_P2V(x)
-#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
-
-/*
- * IRQ
- */
-#define MX23_INT_DUART 0
-#define MX23_INT_COMMS_RX 1
-#define MX23_INT_COMMS_TX 1
-#define MX23_INT_SSP2_ERROR 2
-#define MX23_INT_VDD5V 3
-#define MX23_INT_HEADPHONE_SHORT 4
-#define MX23_INT_DAC_DMA 5
-#define MX23_INT_DAC_ERROR 6
-#define MX23_INT_ADC_DMA 7
-#define MX23_INT_ADC_ERROR 8
-#define MX23_INT_SPDIF_DMA 9
-#define MX23_INT_SAIF2_DMA 9
-#define MX23_INT_SPDIF_ERROR 10
-#define MX23_INT_SAIF1_IRQ 10
-#define MX23_INT_SAIF2_IRQ 10
-#define MX23_INT_USB_CTRL 11
-#define MX23_INT_USB_WAKEUP 12
-#define MX23_INT_GPMI_DMA 13
-#define MX23_INT_SSP1_DMA 14
-#define MX23_INT_SSP1_ERROR 15
-#define MX23_INT_GPIO0 16
-#define MX23_INT_GPIO1 17
-#define MX23_INT_GPIO2 18
-#define MX23_INT_SAIF1_DMA 19
-#define MX23_INT_SSP2_DMA 20
-#define MX23_INT_ECC8_IRQ 21
-#define MX23_INT_RTC_ALARM 22
-#define MX23_INT_AUART1_TX_DMA 23
-#define MX23_INT_AUART1 24
-#define MX23_INT_AUART1_RX_DMA 25
-#define MX23_INT_I2C_DMA 26
-#define MX23_INT_I2C_ERROR 27
-#define MX23_INT_TIMER0 28
-#define MX23_INT_TIMER1 29
-#define MX23_INT_TIMER2 30
-#define MX23_INT_TIMER3 31
-#define MX23_INT_BATT_BRNOUT 32
-#define MX23_INT_VDDD_BRNOUT 33
-#define MX23_INT_VDDIO_BRNOUT 34
-#define MX23_INT_VDD18_BRNOUT 35
-#define MX23_INT_TOUCH_DETECT 36
-#define MX23_INT_LRADC_CH0 37
-#define MX23_INT_LRADC_CH1 38
-#define MX23_INT_LRADC_CH2 39
-#define MX23_INT_LRADC_CH3 40
-#define MX23_INT_LRADC_CH4 41
-#define MX23_INT_LRADC_CH5 42
-#define MX23_INT_LRADC_CH6 43
-#define MX23_INT_LRADC_CH7 44
-#define MX23_INT_LCDIF_DMA 45
-#define MX23_INT_LCDIF_ERROR 46
-#define MX23_INT_DIGCTL_DEBUG_TRAP 47
-#define MX23_INT_RTC_1MSEC 48
-#define MX23_INT_DRI_DMA 49
-#define MX23_INT_DRI_ATTENTION 50
-#define MX23_INT_GPMI_ATTENTION 51
-#define MX23_INT_IR 52
-#define MX23_INT_DCP_VMI 53
-#define MX23_INT_DCP 54
-#define MX23_INT_BCH 56
-#define MX23_INT_PXP 57
-#define MX23_INT_AUART2_TX_DMA 58
-#define MX23_INT_AUART2 59
-#define MX23_INT_AUART2_RX_DMA 60
-#define MX23_INT_VDAC_DETECT 61
-#define MX23_INT_VDD5V_DROOP 64
-#define MX23_INT_DCDC4P2_BO 65
-
-/*
- * APBH DMA
- */
-#define MX23_DMA_SSP1 1
-#define MX23_DMA_SSP2 2
-#define MX23_DMA_GPMI0 4
-#define MX23_DMA_GPMI1 5
-#define MX23_DMA_GPMI2 6
-#define MX23_DMA_GPMI3 7
-
-/*
- * APBX DMA
- */
-#define MX23_DMA_ADC 0
-#define MX23_DMA_DAC 1
-#define MX23_DMA_SPDIF 2
-#define MX23_DMA_I2C 3
-#define MX23_DMA_SAIF0 4
-#define MX23_DMA_UART0_RX 6
-#define MX23_DMA_UART0_TX 7
-#define MX23_DMA_UART1_RX 8
-#define MX23_DMA_UART1_TX 9
-#define MX23_DMA_SAIF1 10
-
-#endif /* __MACH_MX23_H__ */
+++ /dev/null
-/*
- * 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.
- */
-
-#ifndef __MACH_MX28_H__
-#define __MACH_MX28_H__
-
-#include <mach/mxs.h>
-
-/*
- * OCRAM
- */
-#define MX28_OCRAM_BASE_ADDR 0x00000000
-#define MX28_OCRAM_SIZE SZ_128K
-
-/*
- * IO
- */
-#define MX28_IO_BASE_ADDR 0x80000000
-#define MX28_IO_SIZE SZ_1M
-
-#define MX28_ICOLL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x000000)
-#define MX28_HSADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x002000)
-#define MX28_APBH_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x004000)
-#define MX28_PERFMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x006000)
-#define MX28_BCH_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00a000)
-#define MX28_GPMI_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00c000)
-#define MX28_SSP0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x010000)
-#define MX28_SSP1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x012000)
-#define MX28_SSP2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x014000)
-#define MX28_SSP3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x016000)
-#define MX28_PINCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x018000)
-#define MX28_DIGCTL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x01c000)
-#define MX28_ETM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x022000)
-#define MX28_APBX_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x024000)
-#define MX28_DCP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x028000)
-#define MX28_PXP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02a000)
-#define MX28_OCOTP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02c000)
-#define MX28_AXI_AHB0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02e000)
-#define MX28_LCDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x030000)
-#define MX28_CAN0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x032000)
-#define MX28_CAN1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x034000)
-#define MX28_SIMDBG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c000)
-#define MX28_SIMGPMISEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c200)
-#define MX28_SIMSSPSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c300)
-#define MX28_SIMMEMSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c400)
-#define MX28_GPIOMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c500)
-#define MX28_SIMENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c700)
-#define MX28_ARMJTAG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c800)
-#define MX28_CLKCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x040000)
-#define MX28_SAIF0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x042000)
-#define MX28_POWER_BASE_ADDR (MX28_IO_BASE_ADDR + 0x044000)
-#define MX28_SAIF1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x046000)
-#define MX28_LRADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x050000)
-#define MX28_SPDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x054000)
-#define MX28_RTC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x056000)
-#define MX28_I2C0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x058000)
-#define MX28_I2C1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x05a000)
-#define MX28_PWM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x064000)
-#define MX28_TIMROT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x068000)
-#define MX28_AUART0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06a000)
-#define MX28_AUART1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06c000)
-#define MX28_AUART2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06e000)
-#define MX28_AUART3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x070000)
-#define MX28_AUART4_BASE_ADDR (MX28_IO_BASE_ADDR + 0x072000)
-#define MX28_DUART_BASE_ADDR (MX28_IO_BASE_ADDR + 0x074000)
-#define MX28_USBPHY0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07C000)
-#define MX28_USBPHY1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07e000)
-#define MX28_USBCTRL0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x080000)
-#define MX28_USBCTRL1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x090000)
-#define MX28_DFLPT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0c0000)
-#define MX28_DRAM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0e0000)
-#define MX28_ENET_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
-#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
-
-#define MX28_IO_P2V(x) MXS_IO_P2V(x)
-#define MX28_IO_ADDRESS(x) IOMEM(MX28_IO_P2V(x))
-
-/*
- * IRQ
- */
-#define MX28_INT_BATT_BRNOUT 0
-#define MX28_INT_VDDD_BRNOUT 1
-#define MX28_INT_VDDIO_BRNOUT 2
-#define MX28_INT_VDDA_BRNOUT 3
-#define MX28_INT_VDD5V_DROOP 4
-#define MX28_INT_DCDC4P2_BRNOUT 5
-#define MX28_INT_VDD5V 6
-#define MX28_INT_CAN0 8
-#define MX28_INT_CAN1 9
-#define MX28_INT_LRADC_TOUCH 10
-#define MX28_INT_HSADC 13
-#define MX28_INT_LRADC_THRESH0 14
-#define MX28_INT_LRADC_THRESH1 15
-#define MX28_INT_LRADC_CH0 16
-#define MX28_INT_LRADC_CH1 17
-#define MX28_INT_LRADC_CH2 18
-#define MX28_INT_LRADC_CH3 19
-#define MX28_INT_LRADC_CH4 20
-#define MX28_INT_LRADC_CH5 21
-#define MX28_INT_LRADC_CH6 22
-#define MX28_INT_LRADC_CH7 23
-#define MX28_INT_LRADC_BUTTON0 24
-#define MX28_INT_LRADC_BUTTON1 25
-#define MX28_INT_PERFMON 27
-#define MX28_INT_RTC_1MSEC 28
-#define MX28_INT_RTC_ALARM 29
-#define MX28_INT_COMMS 31
-#define MX28_INT_EMI_ERR 32
-#define MX28_INT_LCDIF 38
-#define MX28_INT_PXP 39
-#define MX28_INT_BCH 41
-#define MX28_INT_GPMI 42
-#define MX28_INT_SPDIF_ERROR 45
-#define MX28_INT_DUART 47
-#define MX28_INT_TIMER0 48
-#define MX28_INT_TIMER1 49
-#define MX28_INT_TIMER2 50
-#define MX28_INT_TIMER3 51
-#define MX28_INT_DCP_VMI 52
-#define MX28_INT_DCP 53
-#define MX28_INT_DCP_SECURE 54
-#define MX28_INT_SAIF1 58
-#define MX28_INT_SAIF0 59
-#define MX28_INT_SPDIF_DMA 66
-#define MX28_INT_I2C0_DMA 68
-#define MX28_INT_I2C1_DMA 69
-#define MX28_INT_AUART0_RX_DMA 70
-#define MX28_INT_AUART0_TX_DMA 71
-#define MX28_INT_AUART1_RX_DMA 72
-#define MX28_INT_AUART1_TX_DMA 73
-#define MX28_INT_AUART2_RX_DMA 74
-#define MX28_INT_AUART2_TX_DMA 75
-#define MX28_INT_AUART3_RX_DMA 76
-#define MX28_INT_AUART3_TX_DMA 77
-#define MX28_INT_AUART4_RX_DMA 78
-#define MX28_INT_AUART4_TX_DMA 79
-#define MX28_INT_SAIF0_DMA 80
-#define MX28_INT_SAIF1_DMA 81
-#define MX28_INT_SSP0_DMA 82
-#define MX28_INT_SSP1_DMA 83
-#define MX28_INT_SSP2_DMA 84
-#define MX28_INT_SSP3_DMA 85
-#define MX28_INT_LCDIF_DMA 86
-#define MX28_INT_HSADC_DMA 87
-#define MX28_INT_GPMI_DMA 88
-#define MX28_INT_DIGCTL_DEBUG_TRAP 89
-#define MX28_INT_USB1 92
-#define MX28_INT_USB0 93
-#define MX28_INT_USB1_WAKEUP 94
-#define MX28_INT_USB0_WAKEUP 95
-#define MX28_INT_SSP0_ERROR 96
-#define MX28_INT_SSP1_ERROR 97
-#define MX28_INT_SSP2_ERROR 98
-#define MX28_INT_SSP3_ERROR 99
-#define MX28_INT_ENET_SWI 100
-#define MX28_INT_ENET_MAC0 101
-#define MX28_INT_ENET_MAC1 102
-#define MX28_INT_ENET_MAC0_1588 103
-#define MX28_INT_ENET_MAC1_1588 104
-#define MX28_INT_I2C1_ERROR 110
-#define MX28_INT_I2C0_ERROR 111
-#define MX28_INT_AUART0 112
-#define MX28_INT_AUART1 113
-#define MX28_INT_AUART2 114
-#define MX28_INT_AUART3 115
-#define MX28_INT_AUART4 116
-#define MX28_INT_GPIO4 123
-#define MX28_INT_GPIO3 124
-#define MX28_INT_GPIO2 125
-#define MX28_INT_GPIO1 126
-#define MX28_INT_GPIO0 127
-
-/*
- * APBH DMA
- */
-#define MX28_DMA_SSP0 0
-#define MX28_DMA_SSP1 1
-#define MX28_DMA_SSP2 2
-#define MX28_DMA_SSP3 3
-#define MX28_DMA_GPMI0 4
-#define MX28_DMA_GPMI1 5
-#define MX28_DMA_GPMI2 6
-#define MX28_DMA_GPMI3 7
-#define MX28_DMA_GPMI4 8
-#define MX28_DMA_GPMI5 9
-#define MX28_DMA_GPMI6 10
-#define MX28_DMA_GPMI7 11
-#define MX28_DMA_HSADC 12
-#define MX28_DMA_LCDIF 13
-
-/*
- * APBX DMA
- */
-#define MX28_DMA_AUART4_RX 0
-#define MX28_DMA_AUART4_TX 1
-#define MX28_DMA_SPDIF_TX 2
-#define MX28_DMA_SAIF0 4
-#define MX28_DMA_SAIF1 5
-#define MX28_DMA_I2C0 6
-#define MX28_DMA_I2C1 7
-#define MX28_DMA_AUART0_RX 8
-#define MX28_DMA_AUART0_TX 9
-#define MX28_DMA_AUART1_RX 10
-#define MX28_DMA_AUART1_TX 11
-#define MX28_DMA_AUART2_RX 12
-#define MX28_DMA_AUART2_TX 13
-#define MX28_DMA_AUART3_RX 14
-#define MX28_DMA_AUART3_TX 15
-
-#endif /* __MACH_MX28_H__ */
+++ /dev/null
-/*
- * 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.
- */
-
-#ifndef __MACH_MXS_H__
-#define __MACH_MXS_H__
-
-#ifndef __ASSEMBLER__
-#include <linux/io.h>
-#endif
-#include <asm/mach-types.h>
-#include <mach/digctl.h>
-#include <mach/hardware.h>
-
-/*
- * IO addresses common to MXS-based
- */
-#define MXS_IO_BASE_ADDR 0x80000000
-#define MXS_IO_SIZE SZ_1M
-
-#define MXS_ICOLL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x000000)
-#define MXS_APBH_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x004000)
-#define MXS_BCH_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00a000)
-#define MXS_GPMI_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00c000)
-#define MXS_PINCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x018000)
-#define MXS_DIGCTL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x01c000)
-#define MXS_APBX_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x024000)
-#define MXS_DCP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x028000)
-#define MXS_PXP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02a000)
-#define MXS_OCOTP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02c000)
-#define MXS_AXI_AHB0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02e000)
-#define MXS_LCDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x030000)
-#define MXS_CLKCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x040000)
-#define MXS_SAIF0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x042000)
-#define MXS_POWER_BASE_ADDR (MXS_IO_BASE_ADDR + 0x044000)
-#define MXS_SAIF1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x046000)
-#define MXS_LRADC_BASE_ADDR (MXS_IO_BASE_ADDR + 0x050000)
-#define MXS_SPDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x054000)
-#define MXS_I2C0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x058000)
-#define MXS_PWM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x064000)
-#define MXS_TIMROT_BASE_ADDR (MXS_IO_BASE_ADDR + 0x068000)
-#define MXS_AUART1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06c000)
-#define MXS_AUART2_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06e000)
-#define MXS_DRAM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x0e0000)
-
-/*
- * It maps the whole address space to [0xf4000000, 0xf50fffff].
- *
- * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
- * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
- */
-#define MXS_IO_P2V(x) (0xf4000000 + \
- (((x) & 0x80000000) >> 7) + \
- (((x) & 0x000fffff)))
-
-#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
-
-#define mxs_map_entry(soc, name, _type) { \
- .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
- .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
- .length = soc ## _ ## name ## _SIZE, \
- .type = _type, \
-}
-
-#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
-
-#define MXS_SET_ADDR 0x4
-#define MXS_CLR_ADDR 0x8
-#define MXS_TOG_ADDR 0xc
-
-#ifndef __ASSEMBLER__
-static inline void __mxs_setl(u32 mask, void __iomem *reg)
-{
- __raw_writel(mask, reg + MXS_SET_ADDR);
-}
-
-static inline void __mxs_clrl(u32 mask, void __iomem *reg)
-{
- __raw_writel(mask, reg + MXS_CLR_ADDR);
-}
-
-static inline void __mxs_togl(u32 mask, void __iomem *reg)
-{
- __raw_writel(mask, reg + MXS_TOG_ADDR);
-}
-
-/*
- * MXS CPU types
- */
-#define MXS_CHIPID (MXS_IO_ADDRESS(MXS_DIGCTL_BASE_ADDR) + HW_DIGCTL_CHIPID)
-
-static inline int cpu_is_mx23(void)
-{
- return ((__raw_readl(MXS_CHIPID) >> 16) == 0x3780);
-}
-
-static inline int cpu_is_mx28(void)
-{
- return ((__raw_readl(MXS_CHIPID) >> 16) == 0x2800);
-}
-#endif
-
-#endif /* __MACH_MXS_H__ */
*/
#include <linux/clk.h>
+#include <linux/clk/mxs.h>
#include <linux/clkdev.h>
+#include <linux/clocksource.h>
#include <linux/can/platform/flexcan.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
+#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>
#include <linux/pinctrl/consumer.h>
#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <mach/common.h>
-#include <mach/digctl.h>
-#include <mach/mxs.h>
-
-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,
- },
-};
+#include <asm/system_misc.h>
-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,
- },
-};
+/* MXS DIGCTL SAIF CLKMUX */
+#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0
+#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3
-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,
- },
-};
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
-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,
- },
-};
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
-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 inline void __mxs_setl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_SET_ADDR);
+}
-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 inline void __mxs_clrl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_CLR_ADDR);
+}
-static struct mxsfb_platform_data mxsfb_pdata __initdata;
+static inline void __mxs_togl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_TOG_ADDR);
+}
/*
* MX28EVK_FLEXCAN_SWITCH is shared between both flexcan controllers
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 */ }
};
-static void __init imx23_timer_init(void)
-{
- mx23_clocks_init();
-}
+#define OCOTP_WORD_OFFSET 0x20
+#define OCOTP_WORD_COUNT 0x20
+
+#define BM_OCOTP_CTRL_BUSY (1 << 8)
+#define BM_OCOTP_CTRL_ERROR (1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
-static void __init imx28_timer_init(void)
+static const u32 *mxs_get_ocotp(void)
{
- mx28_clocks_init();
+ struct device_node *np;
+ void __iomem *ocotp_base;
+ int timeout = 0x400;
+ size_t i;
+ static int once;
+
+ if (once)
+ return ocotp_words;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,ocotp");
+ ocotp_base = of_iomap(np, 0);
+ WARN_ON(!ocotp_base);
+
+ mutex_lock(&ocotp_mutex);
+
+ /*
+ * clk_enable(hbus_clk) for ocotp can be skipped
+ * as it must be on when system is running.
+ */
+
+ /* try to clear ERROR bit */
+ __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+ /* check both BUSY and ERROR cleared */
+ while ((__raw_readl(ocotp_base) &
+ (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ /* open OCOTP banks for read */
+ __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ /* approximately wait 32 hclk cycles */
+ udelay(1);
+
+ /* poll BUSY bit becoming cleared */
+ timeout = 0x400;
+ while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ for (i = 0; i < OCOTP_WORD_COUNT; i++)
+ ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+ i * 0x10);
+
+ /* close banks for power saving */
+ __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ once = 1;
+
+ mutex_unlock(&ocotp_mutex);
+
+ return ocotp_words;
+
+error_unlock:
+ mutex_unlock(&ocotp_mutex);
+ pr_err("%s: timeout in reading OCOTP\n", __func__);
+ return NULL;
}
enum mac_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);
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);
}
}
}
-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;
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)
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);
imx28_evk_post_init();
}
-static const char *imx23_dt_compat[] __initdata = {
- "fsl,imx23",
- NULL,
-};
+#define MX23_CLKCTRL_RESET_OFFSET 0x120
+#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
+#define MXS_CLKCTRL_RESET_CHIP (1 << 1)
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+static void mxs_restart(char mode, const char *cmd)
+{
+ struct device_node *np;
+ void __iomem *reset_addr;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
+ reset_addr = of_iomap(np, 0);
+ if (!reset_addr)
+ goto soft;
+
+ if (of_device_is_compatible(np, "fsl,imx23-clkctrl"))
+ reset_addr += MX23_CLKCTRL_RESET_OFFSET;
+ else
+ reset_addr += MX28_CLKCTRL_RESET_OFFSET;
+
+ /* reset the chip */
+ __mxs_setl(MXS_CLKCTRL_RESET_CHIP, reset_addr);
+
+ pr_err("Failed to assert the chip reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+soft:
+ /* We'll take a jump through zero as a poor second */
+ soft_restart(0);
+}
-static const char *imx28_dt_compat[] __initdata = {
+static void __init mxs_timer_init(void)
+{
+ if (of_machine_is_compatible("fsl,imx23"))
+ mx23_clocks_init();
+ else
+ mx28_clocks_init();
+ clocksource_of_init();
+}
+
+static const char *mxs_dt_compat[] __initdata = {
"fsl,imx28",
+ "fsl,imx23",
NULL,
};
-DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
- .map_io = mx23_map_io,
- .init_irq = icoll_init_irq,
- .handle_irq = icoll_handle_irq,
- .init_time = imx23_timer_init,
- .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 = icoll_init_irq,
+DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
+ .map_io = debug_ll_io_init,
+ .init_irq = irqchip_init,
.handle_irq = icoll_handle_irq,
- .init_time = imx28_timer_init,
+ .init_time = mxs_timer_init,
.init_machine = mxs_machine_init,
- .dt_compat = imx28_dt_compat,
+ .dt_compat = mxs_dt_compat,
.restart = mxs_restart,
MACHINE_END
+++ /dev/null
-/*
- * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * 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
- *
- * Create static mapping between physical to virtual memory.
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/mx23.h>
-#include <mach/mx28.h>
-#include <mach/common.h>
-
-/*
- * Define the MX23 memory map.
- */
-static struct map_desc mx23_io_desc[] __initdata = {
- mxs_map_entry(MX23, OCRAM, MT_DEVICE),
- mxs_map_entry(MX23, IO, MT_DEVICE),
-};
-
-/*
- * Define the MX28 memory map.
- */
-static struct map_desc mx28_io_desc[] __initdata = {
- mxs_map_entry(MX28, OCRAM, MT_DEVICE),
- mxs_map_entry(MX28, IO, MT_DEVICE),
-};
-
-/*
- * This function initializes the memory map. It is called during the
- * system startup to create static physical to virtual memory mappings
- * for the IO modules.
- */
-void __init mx23_map_io(void)
-{
- iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
-}
-
-void __init mx28_map_io(void)
-{
- iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
-}
+++ /dev/null
-/*
- * Copyright 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.
- */
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-
-#include <asm/processor.h> /* for cpu_relax() */
-
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-#define OCOTP_WORD_OFFSET 0x20
-#define OCOTP_WORD_COUNT 0x20
-
-#define BM_OCOTP_CTRL_BUSY (1 << 8)
-#define BM_OCOTP_CTRL_ERROR (1 << 9)
-#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
-
-static DEFINE_MUTEX(ocotp_mutex);
-static u32 ocotp_words[OCOTP_WORD_COUNT];
-
-const u32 *mxs_get_ocotp(void)
-{
- void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
- int timeout = 0x400;
- size_t i;
- static int once = 0;
-
- if (once)
- return ocotp_words;
-
- mutex_lock(&ocotp_mutex);
-
- /*
- * clk_enable(hbus_clk) for ocotp can be skipped
- * as it must be on when system is running.
- */
-
- /* try to clear ERROR bit */
- __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
-
- /* check both BUSY and ERROR cleared */
- while ((__raw_readl(ocotp_base) &
- (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
- cpu_relax();
-
- if (unlikely(!timeout))
- goto error_unlock;
-
- /* open OCOTP banks for read */
- __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
-
- /* approximately wait 32 hclk cycles */
- udelay(1);
-
- /* poll BUSY bit becoming cleared */
- timeout = 0x400;
- while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
- cpu_relax();
-
- if (unlikely(!timeout))
- goto error_unlock;
-
- for (i = 0; i < OCOTP_WORD_COUNT; i++)
- ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
- i * 0x10);
-
- /* close banks for power saving */
- __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
-
- once = 1;
-
- mutex_unlock(&ocotp_mutex);
-
- return ocotp_words;
-
-error_unlock:
- mutex_unlock(&ocotp_mutex);
- pr_err("%s: timeout in reading OCOTP\n", __func__);
- return NULL;
-}
+++ /dev/null
-/*
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/proc-fns.h>
-#include <asm/system_misc.h>
-
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-#define MX23_CLKCTRL_RESET_OFFSET 0x120
-#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
-#define MXS_CLKCTRL_RESET_CHIP (1 << 1)
-
-#define MXS_MODULE_CLKGATE (1 << 30)
-#define MXS_MODULE_SFTRST (1 << 31)
-
-static void __iomem *mxs_clkctrl_reset_addr;
-
-/*
- * Reset the system. It is called by machine_restart().
- */
-void mxs_restart(char mode, const char *cmd)
-{
- /* reset the chip */
- __mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr);
-
- pr_err("Failed to assert the chip reset\n");
-
- /* Delay to allow the serial port to show the message */
- mdelay(50);
-
- /* We'll take a jump through zero as a poor second */
- soft_restart(0);
-}
-
-static int __init mxs_arch_reset_init(void)
-{
- struct clk *clk;
-
- mxs_clkctrl_reset_addr = MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) +
- (cpu_is_mx23() ? MX23_CLKCTRL_RESET_OFFSET :
- MX28_CLKCTRL_RESET_OFFSET);
-
- clk = clk_get_sys("rtc", NULL);
- if (!IS_ERR(clk))
- clk_prepare_enable(clk);
-
- return 0;
-}
-core_initcall(mxs_arch_reset_init);
-
-/*
- * Clear the bit and poll it cleared. This is usually called with
- * a reset address and mask being either SFTRST(bit 31) or CLKGATE
- * (bit 30).
- */
-static int clear_poll_bit(void __iomem *addr, u32 mask)
-{
- int timeout = 0x400;
-
- /* clear the bit */
- __mxs_clrl(mask, addr);
-
- /*
- * SFTRST needs 3 GPMI clocks to settle, the reference manual
- * recommends to wait 1us.
- */
- udelay(1);
-
- /* poll the bit becoming clear */
- while ((__raw_readl(addr) & mask) && --timeout)
- /* nothing */;
-
- return !timeout;
-}
-
-int mxs_reset_block(void __iomem *reset_addr)
-{
- int ret;
- int timeout = 0x400;
-
- /* clear and poll SFTRST */
- ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
- if (unlikely(ret))
- goto error;
-
- /* clear CLKGATE */
- __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
-
- /* set SFTRST to reset the block */
- __mxs_setl(MXS_MODULE_SFTRST, reset_addr);
- udelay(1);
-
- /* poll CLKGATE becoming set */
- while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
- /* nothing */;
- if (unlikely(!timeout))
- goto error;
-
- /* clear and poll SFTRST */
- ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
- if (unlikely(ret))
- goto error;
-
- /* clear and poll CLKGATE */
- ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
- if (unlikely(ret))
- goto error;
-
- return 0;
-
-error:
- pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
- return -ETIMEDOUT;
-}
-EXPORT_SYMBOL(mxs_reset_block);
+++ /dev/null
-/*
- * Copyright (C) 2000-2001 Deep Blue Solutions
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
- * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
- * Copyright (C) 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/err.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-
-#include <asm/mach/time.h>
-#include <asm/sched_clock.h>
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-/*
- * There are 2 versions of the timrot on Freescale MXS-based SoCs.
- * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
- * extends the counter to 32 bits.
- *
- * The implementation uses two timers, one for clock_event and
- * another for clocksource. MX28 uses timrot 0 and 1, while MX23
- * uses 0 and 2.
- */
-
-#define MX23_TIMROT_VERSION_OFFSET 0x0a0
-#define MX28_TIMROT_VERSION_OFFSET 0x120
-#define BP_TIMROT_MAJOR_VERSION 24
-#define BV_TIMROT_VERSION_1 0x01
-#define BV_TIMROT_VERSION_2 0x02
-#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
-
-/*
- * There are 4 registers for each timrotv2 instance, and 2 registers
- * for each timrotv1. So address step 0x40 in macros below strides
- * one instance of timrotv2 while two instances of timrotv1.
- *
- * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
- * on MX28 while timrot2 on MX23.
- */
-/* common between v1 and v2 */
-#define HW_TIMROT_ROTCTRL 0x00
-#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
-/* v1 only */
-#define HW_TIMROT_TIMCOUNTn(n) (0x30 + (n) * 0x40)
-/* v2 only */
-#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
-#define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
-
-#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
-#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
-#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
-#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
-#define BP_TIMROT_TIMCTRLn_SELECT 0
-#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
-#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
-#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf
-
-static struct clock_event_device mxs_clockevent_device;
-static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
-
-static void __iomem *mxs_timrot_base = MXS_IO_ADDRESS(MXS_TIMROT_BASE_ADDR);
-static u32 timrot_major_version;
-
-static inline void timrot_irq_disable(void)
-{
- __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ_EN,
- mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-}
-
-static inline void timrot_irq_enable(void)
-{
- __mxs_setl(BM_TIMROT_TIMCTRLn_IRQ_EN,
- mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-}
-
-static void timrot_irq_acknowledge(void)
-{
- __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ,
- mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-}
-
-static cycle_t timrotv1_get_cycles(struct clocksource *cs)
-{
- return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
- & 0xffff0000) >> 16);
-}
-
-static int timrotv1_set_next_event(unsigned long evt,
- struct clock_event_device *dev)
-{
- /* timrot decrements the count */
- __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
-
- return 0;
-}
-
-static int timrotv2_set_next_event(unsigned long evt,
- struct clock_event_device *dev)
-{
- /* timrot decrements the count */
- __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
-
- return 0;
-}
-
-static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *evt = dev_id;
-
- timrot_irq_acknowledge();
- evt->event_handler(evt);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction mxs_timer_irq = {
- .name = "MXS Timer Tick",
- .dev_id = &mxs_clockevent_device,
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
- .handler = mxs_timer_interrupt,
-};
-
-#ifdef DEBUG
-static const char *clock_event_mode_label[] const = {
- [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
- [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
- [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
- [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
-};
-#endif /* DEBUG */
-
-static void mxs_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- /* Disable interrupt in timer module */
- timrot_irq_disable();
-
- if (mode != mxs_clockevent_mode) {
- /* Set event time into the furthest future */
- if (timrot_is_v1())
- __raw_writel(0xffff,
- mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
- else
- __raw_writel(0xffffffff,
- mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
-
- /* Clear pending interrupt */
- timrot_irq_acknowledge();
- }
-
-#ifdef DEBUG
- pr_info("%s: changing mode from %s to %s\n", __func__,
- clock_event_mode_label[mxs_clockevent_mode],
- clock_event_mode_label[mode]);
-#endif /* DEBUG */
-
- /* Remember timer mode */
- mxs_clockevent_mode = mode;
-
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- pr_err("%s: Periodic mode is not implemented\n", __func__);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- timrot_irq_enable();
- break;
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_RESUME:
- /* Left event sources disabled, no more interrupts appear */
- break;
- }
-}
-
-static struct clock_event_device mxs_clockevent_device = {
- .name = "mxs_timrot",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = mxs_set_mode,
- .set_next_event = timrotv2_set_next_event,
- .rating = 200,
-};
-
-static int __init mxs_clockevent_init(struct clk *timer_clk)
-{
- if (timrot_is_v1())
- mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
- mxs_clockevent_device.cpumask = cpumask_of(0);
- clockevents_config_and_register(&mxs_clockevent_device,
- clk_get_rate(timer_clk),
- timrot_is_v1() ? 0xf : 0x2,
- timrot_is_v1() ? 0xfffe : 0xfffffffe);
-
- return 0;
-}
-
-static struct clocksource clocksource_mxs = {
- .name = "mxs_timer",
- .rating = 200,
- .read = timrotv1_get_cycles,
- .mask = CLOCKSOURCE_MASK(16),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static u32 notrace mxs_read_sched_clock_v2(void)
-{
- return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
-}
-
-static int __init mxs_clocksource_init(struct clk *timer_clk)
-{
- unsigned int c = clk_get_rate(timer_clk);
-
- if (timrot_is_v1())
- clocksource_register_hz(&clocksource_mxs, c);
- else {
- clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
- "mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
- setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
- }
-
- return 0;
-}
-
-void __init mxs_timer_init(void)
-{
- struct device_node *np;
- struct clk *timer_clk;
- int irq;
-
- np = of_find_compatible_node(NULL, NULL, "fsl,timrot");
- if (!np) {
- pr_err("%s: failed find timrot node\n", __func__);
- return;
- }
-
- 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);
-
- /*
- * Initialize timers to a known state
- */
- mxs_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
-
- /* get timrot version */
- timrot_major_version = __raw_readl(mxs_timrot_base +
- (cpu_is_mx23() ? MX23_TIMROT_VERSION_OFFSET :
- MX28_TIMROT_VERSION_OFFSET));
- timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
-
- /* one for clock_event */
- __raw_writel((timrot_is_v1() ?
- BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
- BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
- BM_TIMROT_TIMCTRLn_UPDATE |
- BM_TIMROT_TIMCTRLn_IRQ_EN,
- mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-
- /* another for clocksource */
- __raw_writel((timrot_is_v1() ?
- BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
- BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
- BM_TIMROT_TIMCTRLn_RELOAD,
- mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
-
- /* set clocksource timer fixed count to the maximum */
- if (timrot_is_v1())
- __raw_writel(0xffff,
- mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
- else
- __raw_writel(0xffffffff,
- mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
-
- /* init and register the timer to the framework */
- mxs_clocksource_init(timer_clk);
- mxs_clockevent_init(timer_clk);
-
- /* Make irqs happen */
- irq = irq_of_parse_and_map(np, 0);
- setup_irq(irq, &mxs_timer_irq);
-}
TI OMAP 1710 H3 board support. Say Y here if you have such
a board.
-config MACH_OMAP_HTCWIZARD
- bool "HTC Wizard"
- depends on ARCH_OMAP850
- help
- HTC Wizard smartphone support (AKA QTEK 9100, ...)
-
config MACH_HERALD
bool "HTC Herald"
depends on ARCH_OMAP850
config OMAP4_ERRATA_I688
bool "OMAP4 errata: Async Bridge Corruption"
- depends on ARCH_OMAP4 && !ARCH_MULTIPLATFORM
+ depends on (ARCH_OMAP4 || SOC_OMAP5) && !ARCH_MULTIPLATFORM
select ARCH_HAS_BARRIERS
help
If a data is stalled inside asynchronous bridge because of back
omap_display_init(&sdp2430_dss_data);
}
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
+#if IS_ENABLED(CONFIG_SMC91X)
static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 5,
OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
}
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = 57,
+ .vcc_gpio = -EINVAL,
+ },
+ {
+ .port = 2,
+ .reset_gpio = 61,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = 57,
- .reset_gpio_port[1] = 61,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
sdp3430_display_init();
enable_board_wakeup_source();
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
}
OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
}
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = 126,
+ .vcc_gpio = -EINVAL,
+ },
+ {
+ .port = 2,
+ .reset_gpio = 61,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = 126,
- .reset_gpio_port[1] = 61,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
board_smc91x_init();
board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
enable_board_wakeup_source();
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
}
};
#endif
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = GPIO_USB_NRESET,
+ .vcc_gpio = GPIO_USB_POWER,
+ .vcc_polarity = 1,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = GPIO_USB_NRESET,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
};
static struct mtd_partition crane_nand_partitions[] = {
return;
}
- ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH,
- "usb_ehci_enable");
- if (ret < 0) {
- pr_err("Can not request GPIO %d\n", GPIO_USB_POWER);
- return;
- }
-
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
}
omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
}
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = 57,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
#else
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
#endif
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = 57,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
{} /* Terminator */
};
-
static void __init am3517_evm_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
/* Configure GPIO for EHCI port */
omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
/* DSS */
{} /* Terminator */
};
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = OMAP_MAX_GPIO_LINES + 6,
+ .vcc_gpio = -EINVAL,
+ },
+ {
+ .port = 2,
+ .reset_gpio = OMAP_MAX_GPIO_LINES + 7,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6,
- .reset_gpio_port[1] = OMAP_MAX_GPIO_LINES + 7,
- .reset_gpio_port[2] = -EINVAL
};
static void __init cm_t35_init_usbh(void)
msleep(1);
}
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
}
#define HSUSB2_RESET_GPIO (147)
#define USB_HUB_RESET_GPIO (152)
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = HSUSB1_RESET_GPIO,
+ .vcc_gpio = -EINVAL,
+ },
+ {
+ .port = 2,
+ .reset_gpio = HSUSB2_RESET_GPIO,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = HSUSB1_RESET_GPIO,
- .reset_gpio_port[1] = HSUSB2_RESET_GPIO,
- .reset_gpio_port[2] = -EINVAL,
};
static int __init cm_t3517_init_usbh(void)
msleep(1);
}
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&cm_t3517_ehci_pdata);
return 0;
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
static const char *omap3_gp_boards_compat[] __initdata = {
"ti,omap3-beagle",
+ "timll,omap3-devkit8000",
NULL,
};
return 0;
}
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
+#if IS_ENABLED(CONFIG_SMC91X)
static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 1,
omap3_pmic_init("twl4030", &igep_twldata);
}
+static struct usbhs_phy_data igep2_phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = IGEP2_GPIO_USBH_NRESET,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
+static struct usbhs_phy_data igep3_phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = IGEP3_GPIO_USBH_NRESET,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL,
};
static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
- .reset_gpio_port[2] = -EINVAL,
};
#ifdef CONFIG_OMAP_MUX
if (machine_is_igep0020()) {
omap_display_init(&igep2_dss_data);
igep2_init_smsc911x();
+ usbhs_init_phys(igep2_phy_data, ARRAY_SIZE(igep2_phy_data));
usbhs_init(&igep2_usbhs_bdata);
} else {
+ usbhs_init_phys(igep3_phy_data, ARRAY_SIZE(igep3_phy_data));
usbhs_init(&igep3_usbhs_bdata);
}
}
#include <linux/mtd/nand.h>
#include <linux/mmc/host.h>
#include <linux/usb/phy.h>
+#include <linux/usb/nop-usb-xceiv.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
static struct gpio_led gpio_leds[];
+/* PHY's VCC regulator might be added later, so flag that we need it */
+static struct nop_usb_xceiv_platform_data hsusb2_phy_data = {
+ .needs_vcc = true,
+};
+
+static struct usbhs_phy_data phy_data[] = {
+ {
+ .port = 2,
+ .reset_gpio = 147,
+ .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */
+ .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */
+ .platform_data = &hsusb2_phy_data,
+ },
+};
+
static int beagle_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
}
dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio;
- gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level,
- "nEN_USB_PWR");
+ /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */
+ phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX;
+ phy_data[0].vcc_polarity = beagle_config.usb_pwr_level;
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
return 0;
}
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 147,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
+
usbhs_init(&usbhs_bdata);
+
board_nand_init(omap3beagle_nand_partitions,
ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
NAND_BUSWIDTH_16, NULL);
static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = {
REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"), /* OMAP ISP */
REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"), /* OMAP ISP */
- REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"),
+ REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */
REGULATOR_SUPPLY("vaux2", NULL),
};
return 0;
}
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = -1, /* set at runtime */
+ .vcc_gpio = -EINVAL,
+ },
+};
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- /* PHY reset GPIO will be runtime programmed based on EVM version */
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
/* setup EHCI phy reset config */
omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
- usbhs_bdata.reset_gpio_port[1] = 21;
+ phy_data[0].reset_gpio = 21;
/* EVM REV >= E can supply 500mA with EXTVBUS programming */
musb_board_data.power = 500;
} else {
/* setup EHCI phy reset on MDC */
omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
- usbhs_bdata.reset_gpio_port[1] = 135;
+ phy_data[0].reset_gpio = 135;
}
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(&musb_board_data);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
board_nand_init(omap3evm_nand_partitions,
ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS,
};
static struct regulator_consumer_supply pandora_usb_phy_supply[] = {
- REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"),
+ REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */
};
/* ads7846 on SPI and 2 nub controllers on I2C */
printk(KERN_ERR "wl1251 board initialisation failed\n");
}
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = 16,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct platform_device *omap3pandora_devices[] __initdata = {
&pandora_leds_gpio,
&pandora_keys_gpio,
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 16,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
spi_register_board_info(omap3pandora_spi_board_info,
ARRAY_SIZE(omap3pandora_spi_board_info));
omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
+
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
gpmc_nand_init(&pandora_nand_data, NULL);
#define OMAP3_STALKER_TS_GPIO 175
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = 21,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct platform_device *omap3_stalker_devices[] __initdata = {
&keys_gpio,
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 21,
- .reset_gpio_port[2] = -EINVAL,
};
#ifdef CONFIG_OMAP_MUX
omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
};
#endif
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = 147,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct platform_device *omap3_touchbook_devices[] __initdata = {
&leds_gpio,
&keys_gpio,
};
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 147,
- .reset_gpio_port[2] = -EINVAL
};
static void omap3_touchbook_poweroff(void)
omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
board_nand_init(omap3touchbook_nand_partitions,
ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS,
#include <linux/ti_wilink_st.h>
#include <linux/usb/musb.h>
#include <linux/usb/phy.h>
+#include <linux/usb/nop-usb-xceiv.h>
#include <linux/wl12xx.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/platform_data/omap-abe-twl6040.h>
.id = -1,
};
+/* PHY device on HS USB Port 1 i.e. nop_usb_xceiv.1 */
+static struct nop_usb_xceiv_platform_data hsusb1_phy_data = {
+ /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
+ .clk_rate = 19200000,
+};
+
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 1,
+ .reset_gpio = GPIO_HUB_NRESET,
+ .vcc_gpio = GPIO_HUB_POWER,
+ .vcc_polarity = 1,
+ .platform_data = &hsusb1_phy_data,
+ },
+};
+
static struct platform_device *panda_devices[] __initdata = {
&leds_gpio,
&wl1271_device,
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
- .phy_reset = false,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
-};
-
-static struct gpio panda_ehci_gpios[] __initdata = {
- { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" },
- { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" },
};
static void __init omap4_ehci_init(void)
{
int ret;
- struct clk *phy_ref_clk;
/* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
- phy_ref_clk = clk_get(NULL, "auxclk3_ck");
- if (IS_ERR(phy_ref_clk)) {
- pr_err("Cannot request auxclk3\n");
- return;
- }
- clk_set_rate(phy_ref_clk, 19200000);
- clk_prepare_enable(phy_ref_clk);
-
- /* disable the power to the usb hub prior to init and reset phy+hub */
- ret = gpio_request_array(panda_ehci_gpios,
- ARRAY_SIZE(panda_ehci_gpios));
- if (ret) {
- pr_err("Unable to initialize EHCI power/reset\n");
- return;
- }
-
- gpio_export(GPIO_HUB_POWER, 0);
- gpio_export(GPIO_HUB_NRESET, 0);
- gpio_set_value(GPIO_HUB_NRESET, 1);
+ ret = clk_add_alias("main_clk", "nop_usb_xceiv.1", "auxclk3_ck", NULL);
+ if (ret)
+ pr_err("Failed to add main_clk alias to auxclk3_ck\n");
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
-
- /* enable power to hub */
- gpio_set_value(GPIO_HUB_POWER, 1);
}
static struct omap_musb_board_data musb_board_data = {
return 0;
}
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = OVERO_GPIO_USBH_NRESET,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET,
- .reset_gpio_port[2] = -EINVAL
};
#ifdef CONFIG_OMAP_MUX
ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL);
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
overo_spi_init();
overo_init_smsc911x();
},
};
+static struct usbhs_phy_data phy_data[] __initdata = {
+ {
+ .port = 2,
+ .reset_gpio = ZOOM3_EHCI_RESET_GPIO,
+ .vcc_gpio = -EINVAL,
+ },
+};
+
static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO,
- .reset_gpio_port[2] = -EINVAL,
};
static void __init omap_zoom_init(void)
} else if (machine_is_omap_zoom3()) {
omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT);
+
+ usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
}
clk_set_parent(&timer3_fck, &sys_clkin_ck);
clk_set_parent(&timer6_fck, &sys_clkin_ck);
+ /*
+ * The On-Chip 32K RC Osc clock is not an accurate clock-source as per
+ * the design/spec, so as a result, for example, timer which supposed
+ * to get expired @60Sec, but will expire somewhere ~@40Sec, which is
+ * not expected by any use-case, so change WDT1 clock source to PRCM
+ * 32KHz clock.
+ */
+ clk_set_parent(&wdt1_fck, &clkdiv32k_ick);
return 0;
}
_omap3_noncore_dpll_bypass(clk);
/*
- * Set jitter correction. No jitter correction for OMAP4 and 3630
- * since freqsel field is no longer present
+ * Set jitter correction. Jitter correction applicable for OMAP343X
+ * only since freqsel field is no longer present on other devices.
*/
- if (!soc_is_am33xx() && !cpu_is_omap44xx() && !cpu_is_omap3630()) {
+ if (cpu_is_omap343x()) {
v = __raw_readl(dd->control_reg);
v &= ~dd->freqsel_mask;
v |= freqsel << __ffs(dd->freqsel_mask);
if (!dd)
return -EINVAL;
- __clk_prepare(dd->clk_bypass);
- clk_enable(dd->clk_bypass);
- __clk_prepare(dd->clk_ref);
- clk_enable(dd->clk_ref);
-
if (__clk_get_rate(dd->clk_bypass) == rate &&
(dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
pr_debug("%s: %s: set rate: entering bypass.\n",
__func__, __clk_get_name(hw->clk));
+ __clk_prepare(dd->clk_bypass);
+ clk_enable(dd->clk_bypass);
ret = _omap3_noncore_dpll_bypass(clk);
if (!ret)
new_parent = dd->clk_bypass;
+ clk_disable(dd->clk_bypass);
+ __clk_unprepare(dd->clk_bypass);
} else {
+ __clk_prepare(dd->clk_ref);
+ clk_enable(dd->clk_ref);
+
if (dd->last_rounded_rate != rate)
rate = __clk_round_rate(hw->clk, rate);
if (dd->last_rounded_rate == 0)
return -EINVAL;
- /* No freqsel on AM335x, OMAP4 and OMAP3630 */
- if (!soc_is_am33xx() && !cpu_is_omap44xx() &&
- !cpu_is_omap3630()) {
+ /* Freqsel is available only on OMAP343X devices */
+ if (cpu_is_omap343x()) {
freqsel = _omap3_dpll_compute_freqsel(clk,
dd->last_rounded_n);
WARN_ON(!freqsel);
ret = omap3_noncore_dpll_program(clk, freqsel);
if (!ret)
new_parent = dd->clk_ref;
+ clk_disable(dd->clk_ref);
+ __clk_unprepare(dd->clk_ref);
}
/*
* FIXME - this is all wrong. common code handles reparenting and
if (!ret)
__clk_reparent(hw->clk, new_parent);
- clk_disable(dd->clk_ref);
- __clk_unprepare(dd->clk_ref);
- clk_disable(dd->clk_bypass);
- __clk_unprepare(dd->clk_bypass);
-
return 0;
}
#include "control.h"
#include "cm2xxx_3xxx.h"
#include "prm2xxx_3xxx.h"
-#ifdef CONFIG_BRIDGE_DVFS
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
#include "omap-pm.h"
#endif
static struct platform_device *omap_dsp_pdev;
static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
-#ifdef CONFIG_BRIDGE_DVFS
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
.dsp_set_min_opp = omap_pm_dsp_set_min_opp,
.dsp_get_opp = omap_pm_dsp_get_opp,
.cpu_set_freq = omap_pm_cpu_set_freq,
case 0xb942:
switch (rev) {
case 0:
- default:
omap_revision = OMAP5430_REV_ES1_0;
+ break;
+ case 1:
+ default:
+ omap_revision = OMAP5430_REV_ES2_0;
}
break;
case 0xb998:
switch (rev) {
case 0:
- default:
omap_revision = OMAP5432_REV_ES1_0;
+ break;
+ case 1:
+ default:
+ omap_revision = OMAP5432_REV_ES2_0;
}
break;
default:
/* Unknown default to latest silicon rev as default*/
- omap_revision = OMAP5430_REV_ES1_0;
+ omap_revision = OMAP5430_REV_ES2_0;
}
pr_info("OMAP%04x ES%d.0\n",
.length = L4_PER_54XX_SIZE,
.type = MT_DEVICE,
},
+#ifdef CONFIG_OMAP4_ERRATA_I688
+ {
+ .virtual = OMAP4_SRAM_VA,
+ .pfn = __phys_to_pfn(OMAP4_SRAM_PA),
+ .length = PAGE_SIZE,
+ .type = MT_MEMORY_SO,
+ },
+#endif
};
#endif
void __init omap5_map_io(void)
{
iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
+ omap_barriers_init();
}
#endif
/*
*/
static int __init omap4_sar_ram_init(void)
{
+ unsigned long sar_base;
+
/*
* To avoid code running on other OMAPs in
* multi-omap builds
*/
- if (!cpu_is_omap44xx())
+ if (cpu_is_omap44xx())
+ sar_base = OMAP44XX_SAR_RAM_BASE;
+ else if (soc_is_omap54xx())
+ sar_base = OMAP54XX_SAR_RAM_BASE;
+ else
return -ENOMEM;
/* Static mapping, never released */
- sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+ sar_ram_base = ioremap(sar_base, SZ_16K);
if (WARN_ON(!sar_ram_base))
return -ENOMEM;
#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10
/* WakeUpGen save restore offset from OMAP54XX_SAR_RAM_BASE */
-#define OMAP5_WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x8d4)
-#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x8e8)
-#define OMAP5_WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x8fc)
-#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x910)
-#define OMAP5_AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x924)
-#define OMAP5_AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x928)
-#define OMAP5_AMBA_IF_MODE_OFFSET (SAR_BANK3_OFFSET + 0x92c)
+#define OMAP5_WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9dc)
+#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9f0)
+#define OMAP5_WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa04)
+#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa18)
+#define OMAP5_AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0xa2c)
+#define OMAP5_AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x930)
+#define OMAP5_AMBA_IF_MODE_OFFSET (SAR_BANK3_OFFSET + 0xa34)
#define OMAP5_SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x800)
#endif
#define OMAP54XX_PRCM_MPU_BASE 0x48243000
#define OMAP54XX_SCM_BASE 0x4a002000
#define OMAP54XX_CTRL_BASE 0x4a002800
+#define OMAP54XX_SAR_RAM_BASE 0x4ae26000
#endif /* __ASM_SOC_OMAP555554XX_H */
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/bootmem.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/system_misc.h>
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
- oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
-
return 0;
}
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
- oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
-
return 0;
}
return 0;
}
+/**
+ * of_dev_hwmod_lookup - look up needed hwmod from dt blob
+ * @np: struct device_node *
+ * @oh: struct omap_hwmod *
+ *
+ * Parse the dt blob and find out needed hwmod. Recursive function is
+ * implemented to take care hierarchical dt blob parsing.
+ * Return: The device node on success or NULL on failure.
+ */
+static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
+ struct omap_hwmod *oh)
+{
+ struct device_node *np0 = NULL, *np1 = NULL;
+ const char *p;
+
+ for_each_child_of_node(np, np0) {
+ if (of_find_property(np0, "ti,hwmods", NULL)) {
+ p = of_get_property(np0, "ti,hwmods", NULL);
+ if (!strcmp(p, oh->name))
+ return np0;
+ np1 = of_dev_hwmod_lookup(np0, oh);
+ if (np1)
+ return np1;
+ }
+ }
+ return NULL;
+}
+
/**
* _init_mpu_rt_base - populate the virtual address for a hwmod
* @oh: struct omap_hwmod * to locate the virtual address
static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
{
struct omap_hwmod_addr_space *mem;
- void __iomem *va_start;
+ void __iomem *va_start = NULL;
+ struct device_node *np;
if (!oh)
return;
if (!mem) {
pr_debug("omap_hwmod: %s: no MPU register target found\n",
oh->name);
- return;
+
+ /* Extract the IO space from device tree blob */
+ if (!of_have_populated_dt())
+ return;
+
+ np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
+ if (np)
+ va_start = of_iomap(np, 0);
+ } else {
+ va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
}
- va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
if (!va_start) {
pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
return;
if (oh->_state != _HWMOD_STATE_REGISTERED)
return 0;
- _init_mpu_rt_base(oh, NULL);
+ if (oh->class->sysc)
+ _init_mpu_rt_base(oh, NULL);
r = _init_clocks(oh, NULL);
if (IS_ERR_VALUE(r)) {
* These are for internal use only and are managed by the omap_hwmod code.
*
* _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
- * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
* _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
* _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) -
* causes the first call to _enable() to only update the pinmux
*/
#define _HWMOD_NO_MPU_PORT (1 << 0)
-#define _HWMOD_WAKEUP_ENABLED (1 << 1)
-#define _HWMOD_SYSCONFIG_LOADED (1 << 2)
-#define _HWMOD_SKIP_ENABLE (1 << 3)
+#define _HWMOD_SYSCONFIG_LOADED (1 << 1)
+#define _HWMOD_SKIP_ENABLE (1 << 2)
/*
* omap_hwmod._state definitions
#include "prm-regbits-33xx.h"
#include "i2c.h"
#include "mmc.h"
+#include "wd_timer.h"
/*
* IP blocks
};
/* 'wd_timer' class */
+static struct omap_hwmod_class_sysconfig wdt_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = {
.name = "wd_timer",
+ .sysc = &wdt_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
};
/*
.name = "wd_timer2",
.class = &am33xx_wd_timer_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
.main_clk = "wdt1_fck",
.prcm = {
.omap4 = {
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
+#include <linux/of.h>
+
#include <asm/pmu.h>
#include "soc.h"
unsigned oh_num;
char **oh_names;
+ /* XXX Remove this check when the CTI driver is available */
+ if (cpu_is_omap443x()) {
+ pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
+ return 0;
+ }
+
+ if (of_have_populated_dt())
+ return 0;
+
/*
* To create an ARM-PMU device the following HWMODs
* are required for the various OMAP2+ devices.
if (cpu_is_omap443x()) {
oh_num = ARRAY_SIZE(omap4430_pmu_oh_names);
oh_names = omap4430_pmu_oh_names;
- /* XXX Remove the next two lines when CTI driver available */
- pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
- return 0;
} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
oh_num = ARRAY_SIZE(omap3_pmu_oh_names);
oh_names = omap3_pmu_oh_names;
#define ALREADYACTIVE_SWITCH 0
#define FORCEWAKEUP_SWITCH 1
#define LOWPOWERSTATE_SWITCH 2
-#define ERROR_SWITCH 3
/* pwrdm_list contains all registered struct powerdomains */
static LIST_HEAD(pwrdm_list);
{
u8 sleep_switch;
- if (curr_pwrst < 0) {
- WARN_ON(1);
- sleep_switch = ERROR_SWITCH;
- } else if (curr_pwrst < PWRDM_POWER_ON) {
+ if (curr_pwrst < PWRDM_POWER_ON) {
if (curr_pwrst > pwrst &&
pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
arch_pwrdm->pwrdm_set_lowpwrstchange) {
*/
int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
{
- u8 curr_pwrst, next_pwrst, sleep_switch;
+ u8 next_pwrst, sleep_switch;
+ int curr_pwrst;
int ret = 0;
bool hwsup = false;
pwrdm_lock(pwrdm);
curr_pwrst = pwrdm_read_pwrst(pwrdm);
+ if (curr_pwrst < 0) {
+ ret = -EINVAL;
+ goto osps_out;
+ }
+
next_pwrst = pwrdm_read_next_pwrst(pwrdm);
if (curr_pwrst == pwrst && next_pwrst == pwrst)
goto osps_out;
sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
pwrst, &hwsup);
- if (sleep_switch == ERROR_SWITCH) {
- ret = -EINVAL;
- goto osps_out;
- }
ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
if (ret)
/* Read a register in a CM/PRM instance in the PRM module */
u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
{
- return __raw_readl(OMAP44XX_PRM_REGADDR(inst, reg));
+ return __raw_readl(prm_base + inst + reg);
}
/* Write into a register in a CM/PRM instance in the PRM module */
void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
{
- __raw_writel(val, OMAP44XX_PRM_REGADDR(inst, reg));
+ __raw_writel(val, prm_base + inst + reg);
}
/* Read-modify-write a register in a PRM module. Caller must lock */
int __init omap44xx_prm_init(void)
{
- if (!cpu_is_omap44xx())
+ if (!cpu_is_omap44xx() && !soc_is_omap54xx())
return 0;
return prm_register(&omap44xx_prm_ll_data);
#define OMAP54XX_CLASS 0x54000054
#define OMAP5430_REV_ES1_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x10 << 8))
+#define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8))
#define OMAP5432_REV_ES1_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x10 << 8))
+#define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8))
void omap2xxx_check_revision(void);
void omap3xxx_check_revision(void);
#define OMAP2_MPU_SOURCE "sys_ck"
#define OMAP3_MPU_SOURCE OMAP2_MPU_SOURCE
#define OMAP4_MPU_SOURCE "sys_clkin_ck"
+#define OMAP5_MPU_SOURCE "sys_clkin"
#define OMAP2_32K_SOURCE "func_32k_ck"
#define OMAP3_32K_SOURCE "omap_32k_fck"
#define OMAP4_32K_SOURCE "sys_32k_ck"
};
static struct of_device_id omap_timer_match[] __initdata = {
- { .compatible = "ti,omap2-timer", },
+ { .compatible = "ti,omap2420-timer", },
+ { .compatible = "ti,omap3430-timer", },
+ { .compatible = "ti,omap4430-timer", },
+ { .compatible = "ti,omap5430-timer", },
+ { .compatible = "ti,am335x-timer", },
+ { .compatible = "ti,am335x-timer-1ms", },
{ }
};
pr_err("%s: ioremap failed\n", __func__);
return;
}
- sys_clk = clk_get(NULL, "sys_clkin_ck");
+ sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE);
if (IS_ERR(sys_clk)) {
pr_err("%s: failed to get system clock handle\n", __func__);
iounmap(base);
int err;
if (of_have_populated_dt()) {
- twd_local_timer_of_register();
+ clocksource_of_init();
return;
}
#ifdef CONFIG_SOC_OMAP5
OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon",
- 2, OMAP4_MPU_SOURCE);
+ 2, OMAP5_MPU_SOURCE);
void __init omap5_realtime_timer_init(void)
{
int err;
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/phy.h>
#include "soc.h"
#include "omap_device.h"
}
#endif
+
+/* Template for PHY regulators */
+static struct fixed_voltage_config hsusb_reg_config = {
+ /* .supply_name filled later */
+ .microvolts = 3300000,
+ .gpio = -1, /* updated later */
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1, /* updated later */
+ .enabled_at_boot = 0, /* keep in RESET */
+ /* .init_data filled later */
+};
+
+static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */
+static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
+
+/**
+ * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
+ * @name: name for the regulator
+ * @dev_id: device id of the device this regulator supplies power to
+ * @dev_supply: supply name that the device expects
+ * @gpio: GPIO number
+ * @polarity: 1 - Active high, 0 - Active low
+ */
+static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
+ int gpio, int polarity)
+{
+ struct regulator_consumer_supply *supplies;
+ struct regulator_init_data *reg_data;
+ struct fixed_voltage_config *config;
+ struct platform_device *pdev;
+ int ret;
+
+ supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
+ if (!supplies)
+ return -ENOMEM;
+
+ supplies->supply = dev_supply;
+ supplies->dev_name = dev_id;
+
+ reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
+ if (!reg_data)
+ return -ENOMEM;
+
+ reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+ reg_data->consumer_supplies = supplies;
+ reg_data->num_consumer_supplies = 1;
+
+ config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
+ GFP_KERNEL);
+ if (!config)
+ return -ENOMEM;
+
+ config->supply_name = name;
+ config->gpio = gpio;
+ config->enable_high = polarity;
+ config->init_data = reg_data;
+
+ /* create a regulator device */
+ pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->id = PLATFORM_DEVID_AUTO;
+ pdev->name = reg_name;
+ pdev->dev.platform_data = config;
+
+ ret = platform_device_register(pdev);
+ if (ret)
+ pr_err("%s: Failed registering regulator %s for %s\n",
+ __func__, name, dev_id);
+
+ return ret;
+}
+
+int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
+{
+ char *rail_name;
+ int i, len;
+ struct platform_device *pdev;
+ char *phy_id;
+
+ /* the phy_id will be something like "nop_usb_xceiv.1" */
+ len = strlen(nop_name) + 3; /* 3 -> ".1" and NULL terminator */
+
+ for (i = 0; i < num_phys; i++) {
+
+ if (!phy->port) {
+ pr_err("%s: Invalid port 0. Must start from 1\n",
+ __func__);
+ continue;
+ }
+
+ /* do we need a NOP PHY device ? */
+ if (!gpio_is_valid(phy->reset_gpio) &&
+ !gpio_is_valid(phy->vcc_gpio))
+ continue;
+
+ /* create a NOP PHY device */
+ pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->id = phy->port;
+ pdev->name = nop_name;
+ pdev->dev.platform_data = phy->platform_data;
+
+ phy_id = kmalloc(len, GFP_KERNEL);
+ if (!phy_id)
+ return -ENOMEM;
+
+ scnprintf(phy_id, len, "nop_usb_xceiv.%d\n",
+ pdev->id);
+
+ if (platform_device_register(pdev)) {
+ pr_err("%s: Failed to register device %s\n",
+ __func__, phy_id);
+ continue;
+ }
+
+ usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
+
+ /* Do we need RESET regulator ? */
+ if (gpio_is_valid(phy->reset_gpio)) {
+
+ rail_name = kmalloc(13, GFP_KERNEL);
+ if (!rail_name)
+ return -ENOMEM;
+
+ scnprintf(rail_name, 13, "hsusb%d_reset", phy->port);
+
+ usbhs_add_regulator(rail_name, phy_id, "reset",
+ phy->reset_gpio, 1);
+ }
+
+ /* Do we need VCC regulator ? */
+ if (gpio_is_valid(phy->vcc_gpio)) {
+
+ rail_name = kmalloc(13, GFP_KERNEL);
+ if (!rail_name)
+ return -ENOMEM;
+
+ scnprintf(rail_name, 13, "hsusb%d_vcc", phy->port);
+
+ usbhs_add_regulator(rail_name, phy_id, "vcc",
+ phy->vcc_gpio, phy->vcc_polarity);
+ }
+
+ phy++;
+ }
+
+ return 0;
+}
#define USBPHY_OTGSESSEND_EN (1 << 20)
#define USBPHY_DATA_POLARITY (1 << 23)
+struct usbhs_phy_data {
+ int port; /* 1 indexed port number */
+ int reset_gpio;
+ int vcc_gpio;
+ bool vcc_polarity; /* 1 active high, 0 active low */
+ void *platform_data;
+};
+
extern void usb_musb_init(struct omap_musb_board_data *board_data);
extern void usbhs_init(struct usbhs_omap_platform_data *pdata);
+extern int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys);
extern void am35x_musb_reset(void);
extern void am35x_musb_phy_power(u8 on);
-obj-y += common.o addr-map.o pci.o irq.o mpp.o
+obj-y += common.o pci.o irq.o mpp.o
obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
+++ /dev/null
-/*
- * arch/arm/mach-orion5x/addr-map.c
- *
- * Address map functions for Marvell Orion 5x SoCs
- *
- * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <plat/addr-map.h>
-#include "common.h"
-
-/*
- * The Orion has fully programmable address map. There's a separate address
- * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB,
- * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
- * address decode windows that allow it to access any of the Orion resources.
- *
- * CPU address decoding --
- * Linux assumes that it is the boot loader that already setup the access to
- * DDR and internal registers.
- * Setup access to PCI and PCIe IO/MEM space is issued by this file.
- * Setup access to various devices located on the device bus interface (e.g.
- * flashes, RTC, etc) should be issued by machine-setup.c according to
- * specific board population (by using orion5x_setup_*_win()).
- *
- * Non-CPU Masters address decoding --
- * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
- * banks only (the typical use case).
- * Setup access for each master to DDR is issued by platform device setup.
- */
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DEV_BUS 1
-#define TARGET_PCI 3
-#define TARGET_PCIE 4
-#define TARGET_SRAM 9
-#define ATTR_PCIE_MEM 0x59
-#define ATTR_PCIE_IO 0x51
-#define ATTR_PCIE_WA 0x79
-#define ATTR_PCI_MEM 0x59
-#define ATTR_PCI_IO 0x51
-#define ATTR_DEV_CS0 0x1e
-#define ATTR_DEV_CS1 0x1d
-#define ATTR_DEV_CS2 0x1b
-#define ATTR_DEV_BOOT 0xf
-#define ATTR_SRAM 0x0
-
-static int __initdata win_alloc_count;
-
-static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
- const int win)
-{
- u32 dev, rev;
-
- orion5x_pcie_id(&dev, &rev);
- if ((dev == MV88F5281_DEV_ID && win < 4)
- || (dev == MV88F5182_DEV_ID && win < 2)
- || (dev == MV88F5181_DEV_ID && win < 2)
- || (dev == MV88F6183_DEV_ID && win < 4))
- return 1;
-
- return 0;
-}
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct orion_addr_map_cfg addr_map_cfg __initdata = {
- .num_wins = 8,
- .cpu_win_can_remap = cpu_win_can_remap,
- .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE,
-};
-
-static const struct __initdata orion_addr_map_info addr_map_info[] = {
- /*
- * Setup windows for PCI+PCIe IO+MEM space.
- */
- { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
- TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE
- },
- { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
- TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE
- },
- { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
- TARGET_PCIE, ATTR_PCIE_MEM, -1
- },
- { 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
- TARGET_PCI, ATTR_PCI_MEM, -1
- },
- /* End marker */
- { -1, 0, 0, 0, 0, 0 }
-};
-
-void __init orion5x_setup_cpu_mbus_bridge(void)
-{
- /*
- * Disable, clear and configure windows.
- */
- orion_config_wins(&addr_map_cfg, addr_map_info);
- win_alloc_count = 4;
-
- /*
- * Setup MBUS dram target info.
- */
- orion_setup_cpu_mbus_target(&addr_map_cfg,
- (void __iomem *) ORION5X_DDR_WINDOW_CPU_BASE);
-}
-
-void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
-{
- orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
- TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
-}
-
-void __init orion5x_setup_dev0_win(u32 base, u32 size)
-{
- orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
- TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
-}
-
-void __init orion5x_setup_dev1_win(u32 base, u32 size)
-{
- orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
- TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
-}
-
-void __init orion5x_setup_dev2_win(u32 base, u32 size)
-{
- orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
- TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
-}
-
-void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
-{
- orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
- TARGET_PCIE, ATTR_PCIE_WA, -1);
-}
-
-void __init orion5x_setup_sram_win(void)
-{
- orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++,
- ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE,
- TARGET_SRAM, ATTR_SRAM, -1);
-}
/*
* Setup Orion address map
*/
- orion5x_setup_cpu_mbus_bridge();
+ orion5x_setup_wins();
/* Setup root of clk tree */
clk_init();
#include <linux/platform_data/usb-ehci-orion.h>
#include <plat/time.h>
#include <plat/common.h>
-#include <plat/addr-map.h>
#include "common.h"
/*****************************************************************************
****************************************************************************/
static void __init orion5x_crypto_init(void)
{
- orion5x_setup_sram_win();
+ mvebu_mbus_add_window("sram", ORION5X_SRAM_PHYS_BASE,
+ ORION5X_SRAM_SIZE);
orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
SZ_8K, IRQ_ORION5X_CESA);
}
****************************************************************************/
void __init orion5x_init_early(void)
{
+ u32 rev, dev;
+ const char *mbus_soc_name;
+
orion_time_set_base(TIMER_VIRT_BASE);
/*
* the allocations won't fail.
*/
init_dma_coherent_pool_size(SZ_1M);
+
+ /* Initialize the MBUS driver */
+ orion5x_pcie_id(&dev, &rev);
+ if (dev == MV88F5281_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f5281-mbus";
+ else if (dev == MV88F5182_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f5182-mbus";
+ else if (dev == MV88F5181_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f5181-mbus";
+ else if (dev == MV88F6183_DEV_ID)
+ mbus_soc_name = "marvell,orion5x-88f6183-mbus";
+ else
+ mbus_soc_name = NULL;
+ mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
+ ORION5X_BRIDGE_WINS_SZ,
+ ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
+}
+
+void orion5x_setup_wins(void)
+{
+ /*
+ * The PCIe windows will no longer be statically allocated
+ * here once Orion5x is migrated to the pci-mvebu driver.
+ */
+ mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_IO_PHYS_BASE,
+ ORION5X_PCIE_IO_SIZE,
+ ORION5X_PCIE_IO_BUS_BASE,
+ MVEBU_MBUS_PCI_IO);
+ mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_MEM_PHYS_BASE,
+ ORION5X_PCIE_MEM_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
+ mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_IO_PHYS_BASE,
+ ORION5X_PCI_IO_SIZE,
+ ORION5X_PCI_IO_BUS_BASE,
+ MVEBU_MBUS_PCI_IO);
+ mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_MEM_PHYS_BASE,
+ ORION5X_PCI_MEM_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_MEM);
}
int orion5x_tclk;
/*
* Setup Orion address map
*/
- orion5x_setup_cpu_mbus_bridge();
+ orion5x_setup_wins();
/* Setup root of clk tree */
clk_init();
extern int orion5x_tclk;
extern void orion5x_timer_init(void);
-/*
- * Enumerations and functions for Orion windows mapping. Used by Orion core
- * functions to map its interfaces and by the machine-setup to map its on-
- * board devices. Details in /mach-orion/addr-map.c
- */
-void orion5x_setup_cpu_mbus_bridge(void);
-void orion5x_setup_dev_boot_win(u32 base, u32 size);
-void orion5x_setup_dev0_win(u32 base, u32 size);
-void orion5x_setup_dev1_win(u32 base, u32 size);
-void orion5x_setup_dev2_win(u32 base, u32 size);
-void orion5x_setup_pcie_wa_win(u32 base, u32 size);
-void orion5x_setup_sram_win(void);
+void orion5x_setup_wins(void);
void orion5x_ehci0_init(void);
void orion5x_ehci1_init(void);
d2net_sata_power_init();
orion5x_sata_init(&d2net_sata_data);
- orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE,
- D2NET_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", D2NET_NOR_BOOT_BASE,
+ D2NET_NOR_BOOT_SIZE);
platform_device_register(&d2net_nor_flash);
platform_device_register(&d2net_gpio_buttons);
orion5x_uart0_init();
orion5x_uart1_init();
- orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE,
- DB88F5281_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", DB88F5281_NOR_BOOT_BASE,
+ DB88F5281_NOR_BOOT_SIZE);
platform_device_register(&db88f5281_boot_flash);
- orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE);
+ mvebu_mbus_add_window("devbus-cs0", DB88F5281_7SEG_BASE,
+ DB88F5281_7SEG_SIZE);
- orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE);
+ mvebu_mbus_add_window("devbus-cs1", DB88F5281_NOR_BASE,
+ DB88F5281_NOR_SIZE);
platform_device_register(&db88f5281_nor_flash);
- orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE);
+ mvebu_mbus_add_window("devbus-cs2", DB88F5281_NAND_BASE,
+ DB88F5281_NAND_SIZE);
platform_device_register(&db88f5281_nand_flash);
i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
/* setup flash mapping
* CS3 holds a 8 MB Spansion S29GL064M90TFIR4
*/
- orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", DNS323_NOR_BOOT_BASE,
+ DNS323_NOR_BOOT_SIZE);
platform_device_register(&dns323_nor_flash);
/* Sort out LEDs, Buttons and i2c devices */
orion5x_ehci0_init();
orion5x_eth_init(&edmini_v2_eth_data);
- orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
- EDMINI_V2_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", EDMINI_V2_NOR_BOOT_BASE,
+ EDMINI_V2_NOR_BOOT_SIZE);
platform_device_register(&edmini_v2_nor_flash);
pr_notice("edmini_v2: USB device port, flash write and power-off "
* Orion Registers Map
******************************************************************************/
+#define ORION5X_DDR_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x00000)
+#define ORION5X_DDR_WINS_BASE (ORION5X_DDR_PHYS_BASE + 0x1500)
+#define ORION5X_DDR_WINS_SZ (0x10)
#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x00000)
-#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE + 0x1500)
#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x10000)
#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x10000)
#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE + (x))
#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x20000)
#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000)
+#define ORION5X_BRIDGE_WINS_BASE (ORION5X_BRIDGE_PHYS_BASE)
+#define ORION5X_BRIDGE_WINS_SZ (0x80)
#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x30000)
orion5x_uart1_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,
- KUROBOX_PRO_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", KUROBOX_PRO_NOR_BOOT_BASE,
+ KUROBOX_PRO_NOR_BOOT_SIZE);
platform_device_register(&kurobox_pro_nor_flash);
if (machine_is_kurobox_pro()) {
- orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE,
- KUROBOX_PRO_NAND_SIZE);
+ mvebu_mbus_add_window("devbus-cs0", KUROBOX_PRO_NAND_BASE,
+ KUROBOX_PRO_NAND_SIZE);
platform_device_register(&kurobox_pro_nand_flash);
}
orion5x_uart0_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE,
- LSCHL_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", LSCHL_NOR_BOOT_BASE,
+ LSCHL_NOR_BOOT_SIZE);
platform_device_register(&lschl_nor_flash);
platform_device_register(&lschl_leds);
orion5x_uart0_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE,
- LS_HGL_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", LS_HGL_NOR_BOOT_BASE,
+ LS_HGL_NOR_BOOT_SIZE);
platform_device_register(&ls_hgl_nor_flash);
platform_device_register(&ls_hgl_button_device);
orion5x_uart0_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
- LSMINI_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", LSMINI_NOR_BOOT_BASE,
+ LSMINI_NOR_BOOT_SIZE);
platform_device_register(&lsmini_nor_flash);
platform_device_register(&lsmini_button_device);
orion5x_uart0_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", MSS2_NOR_BOOT_BASE,
+ MSS2_NOR_BOOT_SIZE);
platform_device_register(&mss2_nor_flash);
platform_device_register(&mss2_button_device);
orion5x_uart0_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", MV2120_NOR_BOOT_BASE,
+ MV2120_NOR_BOOT_SIZE);
platform_device_register(&mv2120_nor_flash);
platform_device_register(&mv2120_button_device);
net2big_sata_power_init();
orion5x_sata_init(&net2big_sata_data);
- orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
- NET2BIG_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", NET2BIG_NOR_BOOT_BASE,
+ NET2BIG_NOR_BOOT_SIZE);
platform_device_register(&net2big_nor_flash);
platform_device_register(&net2big_gpio_buttons);
if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
"read transaction workaround\n");
- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
- ORION5X_PCIE_WA_SIZE);
+ mvebu_mbus_add_window_remap_flags("pcie0.0",
+ ORION5X_PCIE_WA_PHYS_BASE,
+ ORION5X_PCIE_WA_SIZE,
+ MVEBU_MBUS_NO_REMAP,
+ MVEBU_MBUS_PCI_WA);
pcie_ops.read = pcie_rd_conf_wa;
}
orion5x_pci_hw_wr_conf(bus_nr, 0, func, reg, 4, val | 0x7);
}
-static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
+static void __init orion5x_setup_pci_wins(void)
{
+ const struct mbus_dram_target_info *dram = mv_mbus_dram_info();
u32 win_enable;
int bus;
int i;
bus = orion5x_pci_local_bus_nr();
for (i = 0; i < dram->num_cs; i++) {
- struct mbus_dram_window *cs = dram->cs + i;
+ const struct mbus_dram_window *cs = dram->cs + i;
u32 func = PCI_CONF_FUNC_BAR_CS(cs->cs_index);
u32 reg;
u32 val;
/*
* Point PCI unit MBUS decode windows to DRAM space.
*/
- orion5x_setup_pci_wins(&orion_mbus_dram_info);
+ orion5x_setup_pci_wins();
/*
* Master + Slave enable
orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
- orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
- RD88F5181L_FXO_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", RD88F5181L_FXO_NOR_BOOT_BASE,
+ RD88F5181L_FXO_NOR_BOOT_SIZE);
platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
}
orion5x_i2c_init();
orion5x_uart0_init();
- orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE,
- RD88F5181L_GE_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", RD88F5181L_GE_NOR_BOOT_BASE,
+ RD88F5181L_GE_NOR_BOOT_SIZE);
platform_device_register(&rd88f5181l_ge_nor_boot_flash);
i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1);
orion5x_uart0_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE,
- RD88F5182_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", RD88F5182_NOR_BOOT_BASE,
+ RD88F5182_NOR_BOOT_SIZE);
- orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
+ mvebu_mbus_add_window("devbus-cs1", RD88F5182_NOR_BASE,
+ RD88F5182_NOR_SIZE);
platform_device_register(&rd88f5182_nor_flash);
platform_device_register(&rd88f5182_gpio_leds);
/*
* Configure peripherals.
*/
- orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
- TSP2_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", TSP2_NOR_BOOT_BASE,
+ TSP2_NOR_BOOT_SIZE);
platform_device_register(&tsp2_nor_flash);
orion5x_ehci0_init();
/*
* Configure peripherals.
*/
- orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE,
- QNAP_TS209_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", QNAP_TS209_NOR_BOOT_BASE,
+ QNAP_TS209_NOR_BOOT_SIZE);
platform_device_register(&qnap_ts209_nor_flash);
orion5x_ehci0_init();
/*
* Configure peripherals.
*/
- orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE,
- QNAP_TS409_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", QNAP_TS409_NOR_BOOT_BASE,
+ QNAP_TS409_NOR_BOOT_SIZE);
platform_device_register(&qnap_ts409_nor_flash);
orion5x_ehci0_init();
orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
- orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE,
- WNR854T_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", WNR854T_NOR_BOOT_BASE,
+ WNR854T_NOR_BOOT_SIZE);
platform_device_register(&wnr854t_nor_flash);
}
orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
- orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
- WRT350N_V2_NOR_BOOT_SIZE);
+ mvebu_mbus_add_window("devbus-boot", WRT350N_V2_NOR_BOOT_BASE,
+ WRT350N_V2_NOR_BOOT_SIZE);
platform_device_register(&wrt350n_v2_nor_flash);
platform_device_register(&wrt350n_v2_leds);
platform_device_register(&wrt350n_v2_button_device);
#include <linux/amba/pl022.h>
#include <linux/clk.h>
+#include <linux/clocksource.h>
#include <linux/dw_dmac.h>
#include <linux/err.h>
#include <linux/of.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/map.h>
-#include <asm/smp_twd.h>
#include <mach/dma.h>
#include <mach/generic.h>
#include <mach/spear.h>
clk_put(pclk);
spear_setup_of_timer();
- twd_local_timer_of_register();
+ clocksource_of_init();
}
obj-y += reset.o
obj-y += reset-handler.o
obj-y += sleep.o
+obj-y += tegra.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI) += pcie.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
-obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
endif
+++ /dev/null
-/*
- * NVIDIA Tegra114 device tree board support
- *
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/clocksource.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-
-static void __init tegra114_dt_init(void)
-{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const tegra114_dt_board_compat[] = {
- "nvidia,tegra114",
- NULL,
-};
-
-DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
- .smp = smp_ops(tegra_smp_ops),
- .map_io = tegra_map_common_io,
- .init_early = tegra114_init_early,
- .init_irq = tegra_dt_init_irq,
- .init_time = clocksource_of_init,
- .init_machine = tegra114_dt_init,
- .init_late = tegra_init_late,
- .restart = tegra_assert_system_reset,
- .dt_compat = tegra114_dt_board_compat,
-MACHINE_END
+++ /dev/null
-/*
- * nVidia Tegra device tree board support
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/irqdomain.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <linux/pda_power.h>
-#include <linux/platform_data/tegra_usb.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/i2c-tegra.h>
-#include <linux/usb/tegra_usb_phy.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/setup.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
- .operating_mode = TEGRA_USB_OTG,
- .power_down_on_bus_suspend = 1,
- .vbus_gpio = -1,
-};
-
-static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
- .reset_gpio = -1,
- .clk = "cdev2",
-};
-
-static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
- .phy_config = &tegra_ehci2_ulpi_phy_config,
- .operating_mode = TEGRA_USB_HOST,
- .power_down_on_bus_suspend = 1,
- .vbus_gpio = -1,
-};
-
-static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
- .operating_mode = TEGRA_USB_HOST,
- .power_down_on_bus_suspend = 1,
- .vbus_gpio = -1,
-};
-
-static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
- &tegra_ehci1_pdata),
- OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
- &tegra_ehci2_pdata),
- OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
- &tegra_ehci3_pdata),
- {}
-};
-
-static void __init tegra_dt_init(void)
-{
- /*
- * Finished with the static registrations now; fill in the missing
- * devices
- */
- of_platform_populate(NULL, of_default_bus_match_table,
- tegra20_auxdata_lookup, NULL);
-}
-
-static void __init trimslice_init(void)
-{
-#ifdef CONFIG_TEGRA_PCI
- int ret;
-
- ret = tegra_pcie_init(true, true);
- if (ret)
- pr_err("tegra_pci_init() failed: %d\n", ret);
-#endif
-}
-
-static void __init harmony_init(void)
-{
-#ifdef CONFIG_TEGRA_PCI
- int ret;
-
- ret = harmony_pcie_init();
- if (ret)
- pr_err("harmony_pcie_init() failed: %d\n", ret);
-#endif
-}
-
-static void __init paz00_init(void)
-{
- tegra_paz00_wifikill_init();
-}
-
-static struct {
- char *machine;
- void (*init)(void);
-} board_init_funcs[] = {
- { "compulab,trimslice", trimslice_init },
- { "nvidia,harmony", harmony_init },
- { "compal,paz00", paz00_init },
-};
-
-static void __init tegra_dt_init_late(void)
-{
- int i;
-
- tegra_init_late();
-
- for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
- if (of_machine_is_compatible(board_init_funcs[i].machine)) {
- board_init_funcs[i].init();
- break;
- }
- }
-}
-
-static const char *tegra20_dt_board_compat[] = {
- "nvidia,tegra20",
- NULL
-};
-
-DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
- .map_io = tegra_map_common_io,
- .smp = smp_ops(tegra_smp_ops),
- .init_early = tegra20_init_early,
- .init_irq = tegra_dt_init_irq,
- .init_time = clocksource_of_init,
- .init_machine = tegra_dt_init,
- .init_late = tegra_dt_init_late,
- .restart = tegra_assert_system_reset,
- .dt_compat = tegra20_dt_board_compat,
-MACHINE_END
+++ /dev/null
-/*
- * arch/arm/mach-tegra/board-dt-tegra30.c
- *
- * NVIDIA Tegra30 device tree board support
- *
- * Copyright (C) 2011 NVIDIA Corporation
- *
- * Derived from:
- *
- * arch/arm/mach-tegra/board-dt-tegra20.c
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static void __init tegra30_dt_init(void)
-{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *tegra30_dt_board_compat[] = {
- "nvidia,tegra30",
- NULL
-};
-
-DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
- .smp = smp_ops(tegra_smp_ops),
- .map_io = tegra_map_common_io,
- .init_early = tegra30_init_early,
- .init_irq = tegra_dt_init_irq,
- .init_time = clocksource_of_init,
- .init_machine = tegra30_dt_init,
- .init_late = tegra_init_late,
- .restart = tegra_assert_system_reset,
- .dt_compat = tegra30_dt_board_compat,
-MACHINE_END
goto err_reg;
}
- regulator_enable(regulator);
+ err = regulator_enable(regulator);
+ if (err) {
+ pr_err("%s: regulator_enable failed: %d\n", __func__, err);
+ goto err_en;
+ }
err = tegra_pcie_init(true, true);
if (err) {
err_pcie:
regulator_disable(regulator);
+err_en:
regulator_put(regulator);
err_reg:
gpio_free(en_vdd_1v05);
void tegra_assert_system_reset(char mode, const char *cmd);
-void __init tegra20_init_early(void);
-void __init tegra30_init_early(void);
-void __init tegra114_init_early(void);
+void __init tegra_init_early(void);
void __init tegra_map_common_io(void);
void __init tegra_init_irq(void);
void __init tegra_dt_init_irq(void);
#include "common.h"
#include "fuse.h"
#include "iomap.h"
+#include "irq.h"
#include "pmc.h"
#include "apbio.h"
#include "sleep.h"
void __init tegra_dt_init_irq(void)
{
tegra_clocks_init();
+ tegra_pmc_init();
tegra_init_irq();
irqchip_init();
+ tegra_legacy_irq_syscore_init();
}
#endif
}
-static void __init tegra_init_early(void)
+void __init tegra_init_early(void)
{
tegra_cpu_reset_handler_init();
tegra_apb_io_init();
tegra_init_fuse();
tegra_init_cache();
- tegra_pmc_init();
tegra_powergate_init();
+ tegra_hotplug_init();
}
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void __init tegra20_init_early(void)
-{
- tegra_init_early();
- tegra20_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void __init tegra30_init_early(void)
-{
- tegra_init_early();
- tegra30_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void __init tegra114_init_early(void)
-{
- tegra_init_early();
-}
-#endif
-
void __init tegra_init_late(void)
{
+ tegra_init_suspend();
tegra_powergate_debugfs_init();
}
struct cpuidle_driver *drv,
int index)
{
- struct cpuidle_state *state = &drv->states[index];
- u32 cpu_on_time = state->exit_latency;
- u32 cpu_off_time = state->target_residency - state->exit_latency;
-
while (tegra20_cpu_is_resettable_soon())
cpu_relax();
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
- tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
+ tegra_idle_lp2_last();
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
struct cpuidle_driver *drv,
int index)
{
- struct cpuidle_state *state = &drv->states[index];
- u32 cpu_on_time = state->exit_latency;
- u32 cpu_off_time = state->target_residency - state->exit_latency;
-
/* All CPUs entering LP2 is not working.
* Don't let CPU0 enter LP2 when any secondary CPU is online.
*/
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
- tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
+ tegra_idle_lp2_last();
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
smp_wmb();
- save_cpu_arch_register();
-
cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
- restore_cpu_arch_register();
-
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
return true;
* arch/arm/mach-tegra/fuse.c
*
* Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Colin Cross <ccross@android.com>
tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
tegra_init_speedo_data = &tegra30_init_speedo_data;
break;
+ case TEGRA114:
+ tegra_init_speedo_data = &tegra114_init_speedo_data;
+ break;
default:
pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
/*
* Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Colin Cross <ccross@android.com>
static inline void tegra30_init_speedo_data(void) {}
#endif
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+void tegra114_init_speedo_data(void);
+#else
+static inline void tegra114_init_speedo_data(void) {}
+#endif
+
#endif
ENTRY(tegra_secondary_startup)
bl v7_invalidate_l1
- /* Enable coresight */
- mov32 r0, 0xC5ACCE55
- mcr p14, 0, r0, c7, c12, 6
b secondary_startup
ENDPROC(tegra_secondary_startup)
/*
- *
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
- * Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. 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 version 2 as
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
+#include "fuse.h"
#include "sleep.h"
static void (*tegra_hotplug_shutdown)(void);
return cpu == 0 ? -EPERM : 0;
}
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-extern void tegra20_hotplug_shutdown(void);
-void __init tegra20_hotplug_init(void)
+void __init tegra_hotplug_init(void)
{
- tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
-}
-#endif
+ if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
+ return;
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-extern void tegra30_hotplug_shutdown(void);
-void __init tegra30_hotplug_init(void)
-{
- tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+ tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+ tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
}
-#endif
* Author:
* Colin Cross <ccross@android.com>
*
- * Copyright (C) 2010, NVIDIA Corporation
+ * Copyright (C) 2010,2013, NVIDIA Corporation
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
#include <linux/io.h>
#include <linux/of.h>
#include <linux/irqchip/arm-gic.h>
+#include <linux/syscore_ops.h>
#include "board.h"
#include "iomap.h"
#define ICTLR_COP_IEP_CLASS 0x3c
#define FIRST_LEGACY_IRQ 32
+#define TEGRA_MAX_NUM_ICTLRS 5
#define SGI_MASK 0xFFFF
IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
};
+#ifdef CONFIG_PM_SLEEP
+static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS];
+static u32 cop_iep[TEGRA_MAX_NUM_ICTLRS];
+static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS];
+static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS];
+
+static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS];
+#endif
+
bool tegra_pending_sgi(void)
{
u32 pending_set;
return 1;
}
+#ifdef CONFIG_PM_SLEEP
+static int tegra_set_wake(struct irq_data *d, unsigned int enable)
+{
+ u32 irq = d->irq;
+ u32 index, mask;
+
+ if (irq < FIRST_LEGACY_IRQ ||
+ irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32)
+ return -EINVAL;
+
+ index = ((irq - FIRST_LEGACY_IRQ) / 32);
+ mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
+ if (enable)
+ ictlr_wake_mask[index] |= mask;
+ else
+ ictlr_wake_mask[index] &= ~mask;
+
+ return 0;
+}
+
+static int tegra_legacy_irq_suspend(void)
+{
+ unsigned long flags;
+ int i;
+
+ local_irq_save(flags);
+ for (i = 0; i < num_ictlrs; i++) {
+ void __iomem *ictlr = ictlr_reg_base[i];
+ /* Save interrupt state */
+ cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER);
+ cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS);
+ cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER);
+ cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
+
+ /* Disable COP interrupts */
+ writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+
+ /* Disable CPU interrupts */
+ writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+
+ /* Enable the wakeup sources of ictlr */
+ writel_relaxed(ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
+ }
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static void tegra_legacy_irq_resume(void)
+{
+ unsigned long flags;
+ int i;
+
+ local_irq_save(flags);
+ for (i = 0; i < num_ictlrs; i++) {
+ void __iomem *ictlr = ictlr_reg_base[i];
+ writel_relaxed(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
+ writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+ writel_relaxed(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
+ writel_relaxed(cop_iep[i], ictlr + ICTLR_COP_IEP_CLASS);
+ writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+ writel_relaxed(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
+ }
+ local_irq_restore(flags);
+}
+
+static struct syscore_ops tegra_legacy_irq_syscore_ops = {
+ .suspend = tegra_legacy_irq_suspend,
+ .resume = tegra_legacy_irq_resume,
+};
+
+int tegra_legacy_irq_syscore_init(void)
+{
+ register_syscore_ops(&tegra_legacy_irq_syscore_ops);
+
+ return 0;
+}
+#else
+#define tegra_set_wake NULL
+#endif
+
void __init tegra_init_irq(void)
{
int i;
gic_arch_extn.irq_mask = tegra_mask;
gic_arch_extn.irq_unmask = tegra_unmask;
gic_arch_extn.irq_retrigger = tegra_retrigger;
+ gic_arch_extn.irq_set_wake = tegra_set_wake;
+ gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND;
/*
* Check if there is a devicetree present, since the GIC will be
bool tegra_pending_sgi(void);
+#ifdef CONFIG_PM_SLEEP
+int tegra_legacy_irq_syscore_init(void);
+#else
+static inline int tegra_legacy_irq_syscore_init(void) { return 0; }
+#endif
+
#endif
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
-#include <mach/powergate.h>
-
#include "fuse.h"
#include "flowctrl.h"
#include "reset.h"
+#include "pmc.h"
#include "common.h"
#include "iomap.h"
-extern void tegra_secondary_startup(void);
-
static cpumask_t tegra_cpu_init_mask;
-#define EVP_CPU_RESET_VECTOR \
- (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
-
static void __cpuinit tegra_secondary_init(unsigned int cpu)
{
/*
cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
}
-static int tegra20_power_up_cpu(unsigned int cpu)
+
+static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- /* Enable the CPU clock. */
- tegra_enable_cpu_clock(cpu);
+ cpu = cpu_logical_map(cpu);
+
+ /*
+ * Force the CPU into reset. The CPU must remain in reset when
+ * the flow controller state is cleared (which will cause the
+ * flow controller to stop driving reset if the CPU has been
+ * power-gated via the flow controller). This will have no
+ * effect on first boot of the CPU since it should already be
+ * in reset.
+ */
+ tegra_put_cpu_in_reset(cpu);
- /* Clear flow controller CSR. */
- flowctrl_write_cpu_csr(cpu, 0);
+ /*
+ * Unhalt the CPU. If the flow controller was used to
+ * power-gate the CPU this will cause the flow controller to
+ * stop driving reset. The CPU will remain in reset because the
+ * clock and reset block is now driving reset.
+ */
+ flowctrl_write_cpu_halt(cpu, 0);
+ tegra_enable_cpu_clock(cpu);
+ flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+ tegra_cpu_out_of_reset(cpu);
return 0;
}
-static int tegra30_power_up_cpu(unsigned int cpu)
+static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- int ret, pwrgateid;
+ int ret;
unsigned long timeout;
- pwrgateid = tegra_cpu_powergate_id(cpu);
- if (pwrgateid < 0)
- return pwrgateid;
+ cpu = cpu_logical_map(cpu);
+ tegra_put_cpu_in_reset(cpu);
+ flowctrl_write_cpu_halt(cpu, 0);
/*
* The power up sequence of cold boot CPU and warm boot CPU
* the IO clamps.
* For cold boot CPU, do not wait. After the cold boot CPU be
* booted, it will run to tegra_secondary_init() and set
- * tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
+ * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
* next time around.
*/
if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
timeout = jiffies + msecs_to_jiffies(50);
do {
- if (!tegra_powergate_is_powered(pwrgateid))
+ if (tegra_pmc_cpu_is_powered(cpu))
goto remove_clamps;
udelay(10);
} while (time_before(jiffies, timeout));
* be un-gated by un-toggling the power gate register
* manually.
*/
- if (!tegra_powergate_is_powered(pwrgateid)) {
- ret = tegra_powergate_power_on(pwrgateid);
+ if (!tegra_pmc_cpu_is_powered(cpu)) {
+ ret = tegra_pmc_cpu_power_on(cpu);
if (ret)
return ret;
/* Wait for the power to come up. */
timeout = jiffies + msecs_to_jiffies(100);
- while (tegra_powergate_is_powered(pwrgateid)) {
+ while (tegra_pmc_cpu_is_powered(cpu)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
udelay(10);
udelay(10);
/* Remove I/O clamps. */
- ret = tegra_powergate_remove_clamping(pwrgateid);
- udelay(10);
+ ret = tegra_pmc_cpu_remove_clamping(cpu);
+ if (ret)
+ return ret;
- /* Clear flow controller CSR. */
- flowctrl_write_cpu_csr(cpu, 0);
+ udelay(10);
+ flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+ tegra_cpu_out_of_reset(cpu);
return 0;
}
-static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- int status;
-
cpu = cpu_logical_map(cpu);
+ return tegra_pmc_cpu_power_on(cpu);
+}
- /*
- * Force the CPU into reset. The CPU must remain in reset when the
- * flow controller state is cleared (which will cause the flow
- * controller to stop driving reset if the CPU has been power-gated
- * via the flow controller). This will have no effect on first boot
- * of the CPU since it should already be in reset.
- */
- tegra_put_cpu_in_reset(cpu);
-
- /*
- * Unhalt the CPU. If the flow controller was used to power-gate the
- * CPU this will cause the flow controller to stop driving reset.
- * The CPU will remain in reset because the clock and reset block
- * is now driving reset.
- */
- flowctrl_write_cpu_halt(cpu, 0);
-
- switch (tegra_chip_id) {
- case TEGRA20:
- status = tegra20_power_up_cpu(cpu);
- break;
- case TEGRA30:
- status = tegra30_power_up_cpu(cpu);
- break;
- default:
- status = -EINVAL;
- break;
- }
-
- if (status)
- goto done;
-
- /* Take the CPU out of reset. */
- tegra_cpu_out_of_reset(cpu);
-done:
- return status;
+static int __cpuinit tegra_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+ return tegra20_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+ return tegra30_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
+ return tegra114_boot_secondary(cpu, idle);
+
+ return -EINVAL;
}
static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/cpu_pm.h>
-#include <linux/clk.h>
+#include <linux/suspend.h>
#include <linux/err.h>
#include <linux/clk/tegra.h>
#include "reset.h"
#include "flowctrl.h"
#include "fuse.h"
+#include "pmc.h"
#include "sleep.h"
-
-#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */
-
-#define PMC_CTRL 0x0
-#define PMC_CPUPWRGOOD_TIMER 0xc8
-#define PMC_CPUPWROFF_TIMER 0xcc
+#include "pmc.h"
#ifdef CONFIG_PM_SLEEP
-static unsigned int g_diag_reg;
static DEFINE_SPINLOCK(tegra_lp2_lock);
-static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-static struct clk *tegra_pclk;
void (*tegra_tear_down_cpu)(void);
-void save_cpu_arch_register(void)
-{
- /* read diagnostic register */
- asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
- return;
-}
-
-void restore_cpu_arch_register(void)
-{
- /* write diagnostic register */
- asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
- return;
-}
-
-static void set_power_timers(unsigned long us_on, unsigned long us_off)
-{
- unsigned long long ticks;
- unsigned long long pclk;
- unsigned long rate;
- static unsigned long tegra_last_pclk;
-
- if (tegra_pclk == NULL) {
- tegra_pclk = clk_get_sys(NULL, "pclk");
- WARN_ON(IS_ERR(tegra_pclk));
- }
-
- rate = clk_get_rate(tegra_pclk);
-
- if (WARN_ON_ONCE(rate <= 0))
- pclk = 100000000;
- else
- pclk = rate;
-
- if ((rate != tegra_last_pclk)) {
- ticks = (us_on * pclk) + 999999ull;
- do_div(ticks, 1000000);
- writel((unsigned long)ticks, pmc + PMC_CPUPWRGOOD_TIMER);
-
- ticks = (us_off * pclk) + 999999ull;
- do_div(ticks, 1000000);
- writel((unsigned long)ticks, pmc + PMC_CPUPWROFF_TIMER);
- wmb();
- }
- tegra_last_pclk = pclk;
-}
-
/*
* restore_cpu_complex
*
tegra_cpu_clock_resume();
flowctrl_cpu_suspend_exit(cpu);
-
- restore_cpu_arch_register();
}
/*
tegra_cpu_clock_suspend();
flowctrl_cpu_suspend_enter(cpu);
-
- save_cpu_arch_register();
}
void tegra_clear_cpu_in_lp2(int phy_cpu_id)
return 0;
}
-void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time)
+void tegra_idle_lp2_last(void)
{
- u32 mode;
-
- /* Only the last cpu down does the final suspend steps */
- mode = readl(pmc + PMC_CTRL);
- mode |= TEGRA_POWER_CPU_PWRREQ_OE;
- writel(mode, pmc + PMC_CTRL);
-
- set_power_timers(cpu_on_time, cpu_off_time);
+ tegra_pmc_pm_set(TEGRA_SUSPEND_LP2);
cpu_cluster_pm_enter();
suspend_cpu_complex();
restore_cpu_complex();
cpu_cluster_pm_exit();
}
+
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+ enum tegra_suspend_mode mode)
+{
+ /* Tegra114 didn't support any suspending mode yet. */
+ if (tegra_chip_id == TEGRA114)
+ return TEGRA_SUSPEND_NONE;
+
+ /*
+ * The Tegra devices only support suspending to LP2 currently.
+ */
+ if (mode > TEGRA_SUSPEND_LP2)
+ return TEGRA_SUSPEND_LP2;
+
+ return mode;
+}
+
+static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {
+ [TEGRA_SUSPEND_NONE] = "none",
+ [TEGRA_SUSPEND_LP2] = "LP2",
+ [TEGRA_SUSPEND_LP1] = "LP1",
+ [TEGRA_SUSPEND_LP0] = "LP0",
+};
+
+static int __cpuinit tegra_suspend_enter(suspend_state_t state)
+{
+ enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
+
+ if (WARN_ON(mode < TEGRA_SUSPEND_NONE ||
+ mode >= TEGRA_MAX_SUSPEND_MODE))
+ return -EINVAL;
+
+ pr_info("Entering suspend state %s\n", lp_state[mode]);
+
+ tegra_pmc_pm_set(mode);
+
+ local_fiq_disable();
+
+ suspend_cpu_complex();
+ switch (mode) {
+ case TEGRA_SUSPEND_LP2:
+ tegra_set_cpu_in_lp2(0);
+ break;
+ default:
+ break;
+ }
+
+ cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+
+ switch (mode) {
+ case TEGRA_SUSPEND_LP2:
+ tegra_clear_cpu_in_lp2(0);
+ break;
+ default:
+ break;
+ }
+ restore_cpu_complex();
+
+ local_fiq_enable();
+
+ return 0;
+}
+
+static const struct platform_suspend_ops tegra_suspend_ops = {
+ .valid = suspend_valid_only_mem,
+ .enter = tegra_suspend_enter,
+};
+
+void __init tegra_init_suspend(void)
+{
+ if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE)
+ return;
+
+ tegra_pmc_suspend_init();
+
+ suspend_set_ops(&tegra_suspend_ops);
+}
#endif
#ifndef _MACH_TEGRA_PM_H_
#define _MACH_TEGRA_PM_H_
+#include "pmc.h"
+
extern unsigned long l2x0_saved_regs_addr;
void save_cpu_arch_register(void);
void tegra_clear_cpu_in_lp2(int phy_cpu_id);
bool tegra_set_cpu_in_lp2(int phy_cpu_id);
-void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time);
+void tegra_idle_lp2_last(void);
extern void (*tegra_tear_down_cpu)(void);
+#ifdef CONFIG_PM_SLEEP
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+ enum tegra_suspend_mode mode);
+void tegra_init_suspend(void);
+#else
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+ enum tegra_suspend_mode mode)
+{
+ return TEGRA_SUSPEND_NONE;
+}
+static inline void tegra_init_suspend(void) {}
+#endif
+
#endif /* _MACH_TEGRA_PM_H_ */
/*
- * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
*/
#include <linux/kernel.h>
+#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/of_address.h>
-#include "iomap.h"
+#include "fuse.h"
+#include "pm.h"
+#include "pmc.h"
+#include "sleep.h"
-#define PMC_CTRL 0x0
-#define PMC_CTRL_INTR_LOW (1 << 17)
+#define TEGRA_POWER_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */
+#define TEGRA_POWER_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */
+#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */
+
+#define PMC_CTRL 0x0
+#define PMC_CTRL_INTR_LOW (1 << 17)
+#define PMC_PWRGATE_TOGGLE 0x30
+#define PMC_PWRGATE_TOGGLE_START (1 << 8)
+#define PMC_REMOVE_CLAMPING 0x34
+#define PMC_PWRGATE_STATUS 0x38
+
+#define PMC_CPUPWRGOOD_TIMER 0xc8
+#define PMC_CPUPWROFF_TIMER 0xcc
+
+#define TEGRA_POWERGATE_PCIE 3
+#define TEGRA_POWERGATE_VDEC 4
+#define TEGRA_POWERGATE_CPU1 9
+#define TEGRA_POWERGATE_CPU2 10
+#define TEGRA_POWERGATE_CPU3 11
+
+static u8 tegra_cpu_domains[] = {
+ 0xFF, /* not available for CPU0 */
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+static DEFINE_SPINLOCK(tegra_powergate_lock);
+
+static void __iomem *tegra_pmc_base;
+static bool tegra_pmc_invert_interrupt;
+static struct clk *tegra_pclk;
+
+struct pmc_pm_data {
+ u32 cpu_good_time; /* CPU power good time in uS */
+ u32 cpu_off_time; /* CPU power off time in uS */
+ u32 core_osc_time; /* Core power good osc time in uS */
+ u32 core_pmu_time; /* Core power good pmu time in uS */
+ u32 core_off_time; /* Core power off time in uS */
+ bool corereq_high; /* Core power request active-high */
+ bool sysclkreq_high; /* System clock request active-high */
+ bool combined_req; /* Combined pwr req for CPU & Core */
+ bool cpu_pwr_good_en; /* CPU power good signal is enabled */
+ u32 lp0_vec_phy_addr; /* The phy addr of LP0 warm boot code */
+ u32 lp0_vec_size; /* The size of LP0 warm boot code */
+ enum tegra_suspend_mode suspend_mode;
+};
+static struct pmc_pm_data pmc_pm_data;
static inline u32 tegra_pmc_readl(u32 reg)
{
- return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+ return readl(tegra_pmc_base + reg);
}
static inline void tegra_pmc_writel(u32 val, u32 reg)
{
- writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+ writel(val, tegra_pmc_base + reg);
+}
+
+static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
+{
+ if (cpuid <= 0 || cpuid >= num_possible_cpus())
+ return -EINVAL;
+ return tegra_cpu_domains[cpuid];
+}
+
+static bool tegra_pmc_powergate_is_powered(int id)
+{
+ return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
+}
+
+static int tegra_pmc_powergate_set(int id, bool new_state)
+{
+ bool old_state;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tegra_powergate_lock, flags);
+
+ old_state = tegra_pmc_powergate_is_powered(id);
+ WARN_ON(old_state == new_state);
+
+ tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
+
+ spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+
+ return 0;
+}
+
+static int tegra_pmc_powergate_remove_clamping(int id)
+{
+ u32 mask;
+
+ /*
+ * Tegra has a bug where PCIE and VDE clamping masks are
+ * swapped relatively to the partition ids.
+ */
+ if (id == TEGRA_POWERGATE_VDEC)
+ mask = (1 << TEGRA_POWERGATE_PCIE);
+ else if (id == TEGRA_POWERGATE_PCIE)
+ mask = (1 << TEGRA_POWERGATE_VDEC);
+ else
+ mask = (1 << id);
+
+ tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
+
+ return 0;
+}
+
+bool tegra_pmc_cpu_is_powered(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return false;
+ return tegra_pmc_powergate_is_powered(id);
}
-#ifdef CONFIG_OF
+int tegra_pmc_cpu_power_on(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return id;
+ return tegra_pmc_powergate_set(id, true);
+}
+
+int tegra_pmc_cpu_remove_clamping(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return id;
+ return tegra_pmc_powergate_remove_clamping(id);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate)
+{
+ unsigned long long ticks;
+ unsigned long long pclk;
+ static unsigned long tegra_last_pclk;
+
+ if (WARN_ON_ONCE(rate <= 0))
+ pclk = 100000000;
+ else
+ pclk = rate;
+
+ if ((rate != tegra_last_pclk)) {
+ ticks = (us_on * pclk) + 999999ull;
+ do_div(ticks, 1000000);
+ tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWRGOOD_TIMER);
+
+ ticks = (us_off * pclk) + 999999ull;
+ do_div(ticks, 1000000);
+ tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWROFF_TIMER);
+ wmb();
+ }
+ tegra_last_pclk = pclk;
+}
+
+enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
+{
+ return pmc_pm_data.suspend_mode;
+}
+
+void tegra_pmc_pm_set(enum tegra_suspend_mode mode)
+{
+ u32 reg;
+ unsigned long rate = 0;
+
+ reg = tegra_pmc_readl(PMC_CTRL);
+ reg |= TEGRA_POWER_CPU_PWRREQ_OE;
+ reg &= ~TEGRA_POWER_EFFECT_LP0;
+
+ switch (mode) {
+ case TEGRA_SUSPEND_LP2:
+ rate = clk_get_rate(tegra_pclk);
+ break;
+ default:
+ break;
+ }
+
+ set_power_timers(pmc_pm_data.cpu_good_time, pmc_pm_data.cpu_off_time,
+ rate);
+
+ tegra_pmc_writel(reg, PMC_CTRL);
+}
+
+void tegra_pmc_suspend_init(void)
+{
+ u32 reg;
+
+ /* Always enable CPU power request */
+ reg = tegra_pmc_readl(PMC_CTRL);
+ reg |= TEGRA_POWER_CPU_PWRREQ_OE;
+ tegra_pmc_writel(reg, PMC_CTRL);
+}
+#endif
+
static const struct of_device_id matches[] __initconst = {
+ { .compatible = "nvidia,tegra114-pmc" },
+ { .compatible = "nvidia,tegra30-pmc" },
{ .compatible = "nvidia,tegra20-pmc" },
{ }
};
-#endif
-void __init tegra_pmc_init(void)
+static void tegra_pmc_parse_dt(void)
{
- /*
- * For now, Harmony is the only board that uses the PMC, and it wants
- * the signal inverted. Seaboard would too if it used the PMC.
- * Hopefully by the time other boards want to use the PMC, everything
- * will be device-tree, or they also want it inverted.
- */
- bool invert_interrupt = true;
- u32 val;
+ struct device_node *np;
+ u32 prop;
+ enum tegra_suspend_mode suspend_mode;
+ u32 core_good_time[2] = {0, 0};
+ u32 lp0_vec[2] = {0, 0};
-#ifdef CONFIG_OF
- if (of_have_populated_dt()) {
- struct device_node *np;
+ np = of_find_matching_node(NULL, matches);
+ BUG_ON(!np);
- invert_interrupt = false;
+ tegra_pmc_base = of_iomap(np, 0);
- np = of_find_matching_node(NULL, matches);
- if (np) {
- if (of_find_property(np, "nvidia,invert-interrupt",
- NULL))
- invert_interrupt = true;
+ tegra_pmc_invert_interrupt = of_property_read_bool(np,
+ "nvidia,invert-interrupt");
+ tegra_pclk = of_clk_get_by_name(np, "pclk");
+ WARN_ON(IS_ERR(tegra_pclk));
+
+ /* Grabbing the power management configurations */
+ if (of_property_read_u32(np, "nvidia,suspend-mode", &prop)) {
+ suspend_mode = TEGRA_SUSPEND_NONE;
+ } else {
+ switch (prop) {
+ case 0:
+ suspend_mode = TEGRA_SUSPEND_LP0;
+ break;
+ case 1:
+ suspend_mode = TEGRA_SUSPEND_LP1;
+ break;
+ case 2:
+ suspend_mode = TEGRA_SUSPEND_LP2;
+ break;
+ default:
+ suspend_mode = TEGRA_SUSPEND_NONE;
+ break;
}
}
-#endif
+ suspend_mode = tegra_pm_validate_suspend_mode(suspend_mode);
+
+ if (of_property_read_u32(np, "nvidia,cpu-pwr-good-time", &prop))
+ suspend_mode = TEGRA_SUSPEND_NONE;
+ pmc_pm_data.cpu_good_time = prop;
+
+ if (of_property_read_u32(np, "nvidia,cpu-pwr-off-time", &prop))
+ suspend_mode = TEGRA_SUSPEND_NONE;
+ pmc_pm_data.cpu_off_time = prop;
+
+ if (of_property_read_u32_array(np, "nvidia,core-pwr-good-time",
+ core_good_time, ARRAY_SIZE(core_good_time)))
+ suspend_mode = TEGRA_SUSPEND_NONE;
+ pmc_pm_data.core_osc_time = core_good_time[0];
+ pmc_pm_data.core_pmu_time = core_good_time[1];
+
+ if (of_property_read_u32(np, "nvidia,core-pwr-off-time",
+ &prop))
+ suspend_mode = TEGRA_SUSPEND_NONE;
+ pmc_pm_data.core_off_time = prop;
+
+ pmc_pm_data.corereq_high = of_property_read_bool(np,
+ "nvidia,core-power-req-active-high");
+
+ pmc_pm_data.sysclkreq_high = of_property_read_bool(np,
+ "nvidia,sys-clock-req-active-high");
+
+ pmc_pm_data.combined_req = of_property_read_bool(np,
+ "nvidia,combined-power-req");
+
+ pmc_pm_data.cpu_pwr_good_en = of_property_read_bool(np,
+ "nvidia,cpu-pwr-good-en");
+
+ if (of_property_read_u32_array(np, "nvidia,lp0-vec", lp0_vec,
+ ARRAY_SIZE(lp0_vec)))
+ if (suspend_mode == TEGRA_SUSPEND_LP0)
+ suspend_mode = TEGRA_SUSPEND_LP1;
+
+ pmc_pm_data.lp0_vec_phy_addr = lp0_vec[0];
+ pmc_pm_data.lp0_vec_size = lp0_vec[1];
+
+ pmc_pm_data.suspend_mode = suspend_mode;
+}
+
+void __init tegra_pmc_init(void)
+{
+ u32 val;
+
+ tegra_pmc_parse_dt();
val = tegra_pmc_readl(PMC_CTRL);
- if (invert_interrupt)
+ if (tegra_pmc_invert_interrupt)
val |= PMC_CTRL_INTR_LOW;
else
val &= ~PMC_CTRL_INTR_LOW;
#ifndef __MACH_TEGRA_PMC_H
#define __MACH_TEGRA_PMC_H
+enum tegra_suspend_mode {
+ TEGRA_SUSPEND_NONE = 0,
+ TEGRA_SUSPEND_LP2, /* CPU voltage off */
+ TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
+ TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
+ TEGRA_MAX_SUSPEND_MODE,
+};
+
+#ifdef CONFIG_PM_SLEEP
+enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
+void tegra_pmc_pm_set(enum tegra_suspend_mode mode);
+void tegra_pmc_suspend_init(void);
+#endif
+
+bool tegra_pmc_cpu_is_powered(int cpuid);
+int tegra_pmc_cpu_power_on(int cpuid);
+int tegra_pmc_cpu_remove_clamping(int cpuid);
+
void tegra_pmc_init(void);
#endif
*/
ENTRY(tegra_resume)
bl v7_invalidate_l1
- /* Enable coresight */
- mov32 r0, 0xC5ACCE55
- mcr p14, 0, r0, c7, c12, 6
cpu_id r0
cmp r0, #0 @ CPU0?
*
* Register usage within the reset handler:
*
+ * Others: scratch
+ * R6 = SoC ID << 8
* R7 = CPU present (to the OS) mask
* R8 = CPU in LP1 state mask
* R9 = CPU in LP2 state mask
ENTRY(__tegra_cpu_reset_handler)
cpsid aif, 0x13 @ SVC mode, interrupts disabled
+
+ mov32 r6, TEGRA_APB_MISC_BASE
+ ldr r6, [r6, #APB_MISC_GP_HIDREV]
+ and r6, r6, #0xff00
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+t20_check:
+ cmp r6, #(0x20 << 8)
+ bne after_t20_check
+t20_errata:
+ # Tegra20 is a Cortex-A9 r1p1
+ mrc p15, 0, r0, c1, c0, 0 @ read system control register
+ orr r0, r0, #1 << 14 @ erratum 716044
+ mcr p15, 0, r0, c1, c0, 0 @ write system control register
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 4 @ erratum 742230
+ orr r0, r0, #1 << 11 @ erratum 751472
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+ b after_errata
+after_t20_check:
+#endif
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+t30_check:
+ cmp r6, #(0x30 << 8)
+ bne after_t30_check
+t30_errata:
+ # Tegra30 is a Cortex-A9 r2p9
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 6 @ erratum 743622
+ orr r0, r0, #1 << 11 @ erratum 751472
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+ b after_errata
+after_t30_check:
+#endif
+after_errata:
mrc p15, 0, r10, c0, c0, 5 @ MPIDR
and r10, r10, #0x3 @ R10 = CPU number
mov r11, #1
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
/* Are we on Tegra20? */
- mov32 r6, TEGRA_APB_MISC_BASE
- ldr r0, [r6, #APB_MISC_GP_HIDREV]
- and r0, r0, #0xff00
- cmp r0, #(0x20 << 8)
+ cmp r6, #(0x20 << 8)
bne 1f
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
- mov32 r6, TEGRA_PMC_BASE
+ mov32 r5, TEGRA_PMC_BASE
mov r0, #0
cmp r10, #0
- strne r0, [r6, #PMC_SCRATCH41]
+ strne r0, [r5, #PMC_SCRATCH41]
1:
#endif
/*
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
void tegra_disable_clean_inv_dcache(void);
#ifdef CONFIG_HOTPLUG_CPU
-void tegra20_hotplug_init(void);
-void tegra30_hotplug_init(void);
+void tegra20_hotplug_shutdown(void);
+void tegra30_hotplug_shutdown(void);
+void tegra_hotplug_init(void);
#else
-static inline void tegra20_hotplug_init(void) {}
-static inline void tegra30_hotplug_init(void) {}
+static inline void tegra_hotplug_init(void) {}
#endif
void tegra20_cpu_shutdown(int cpu);
--- /dev/null
+/*
+ * NVIDIA Tegra SoC device tree board support
+ *
+ * Copyright (C) 2011, 2013, NVIDIA Corporation
+ * Copyright (C) 2010 Secret Lab Technologies, Ltd.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clocksource.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/pda_power.h>
+#include <linux/platform_data/tegra_usb.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-tegra.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/usb/tegra_usb_phy.h>
+#include <linux/clk/tegra.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include "board.h"
+#include "common.h"
+#include "fuse.h"
+#include "iomap.h"
+
+static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
+ .operating_mode = TEGRA_USB_OTG,
+ .power_down_on_bus_suspend = 1,
+ .vbus_gpio = -1,
+};
+
+static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
+ .reset_gpio = -1,
+ .clk = "cdev2",
+};
+
+static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
+ .phy_config = &tegra_ehci2_ulpi_phy_config,
+ .operating_mode = TEGRA_USB_HOST,
+ .power_down_on_bus_suspend = 1,
+ .vbus_gpio = -1,
+};
+
+static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
+ .operating_mode = TEGRA_USB_HOST,
+ .power_down_on_bus_suspend = 1,
+ .vbus_gpio = -1,
+};
+
+static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
+ &tegra_ehci1_pdata),
+ OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
+ &tegra_ehci2_pdata),
+ OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
+ &tegra_ehci3_pdata),
+ {}
+};
+
+static void __init tegra_dt_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct device *parent = NULL;
+
+ tegra_clocks_apply_init_table();
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ goto out;
+
+ soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision);
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id);
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->family);
+ kfree(soc_dev_attr->revision);
+ kfree(soc_dev_attr->soc_id);
+ kfree(soc_dev_attr);
+ goto out;
+ }
+
+ parent = soc_device_to_device(soc_dev);
+
+ /*
+ * Finished with the static registrations now; fill in the missing
+ * devices
+ */
+out:
+ of_platform_populate(NULL, of_default_bus_match_table,
+ tegra20_auxdata_lookup, parent);
+}
+
+static void __init trimslice_init(void)
+{
+#ifdef CONFIG_TEGRA_PCI
+ int ret;
+
+ ret = tegra_pcie_init(true, true);
+ if (ret)
+ pr_err("tegra_pci_init() failed: %d\n", ret);
+#endif
+}
+
+static void __init harmony_init(void)
+{
+#ifdef CONFIG_TEGRA_PCI
+ int ret;
+
+ ret = harmony_pcie_init();
+ if (ret)
+ pr_err("harmony_pcie_init() failed: %d\n", ret);
+#endif
+}
+
+static void __init paz00_init(void)
+{
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra_paz00_wifikill_init();
+}
+
+static struct {
+ char *machine;
+ void (*init)(void);
+} board_init_funcs[] = {
+ { "compulab,trimslice", trimslice_init },
+ { "nvidia,harmony", harmony_init },
+ { "compal,paz00", paz00_init },
+};
+
+static void __init tegra_dt_init_late(void)
+{
+ int i;
+
+ tegra_init_late();
+
+ for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
+ if (of_machine_is_compatible(board_init_funcs[i].machine)) {
+ board_init_funcs[i].init();
+ break;
+ }
+ }
+}
+
+static const char * const tegra_dt_board_compat[] = {
+ "nvidia,tegra114",
+ "nvidia,tegra30",
+ "nvidia,tegra20",
+ NULL
+};
+
+DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
+ .map_io = tegra_map_common_io,
+ .smp = smp_ops(tegra_smp_ops),
+ .init_early = tegra_init_early,
+ .init_irq = tegra_dt_init_irq,
+ .init_time = clocksource_of_init,
+ .init_machine = tegra_dt_init,
+ .init_late = tegra_dt_init_late,
+ .restart = tegra_assert_system_reset,
+ .dt_compat = tegra_dt_board_compat,
+MACHINE_END
--- /dev/null
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS_NUM 2
+#define CPU_PROCESS_CORNERS_NUM 2
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
+ {1123, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
+ {1695, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold)
+{
+ u32 tmp;
+
+ switch (sku) {
+ case 0x00:
+ case 0x10:
+ case 0x05:
+ case 0x06:
+ tegra_cpu_speedo_id = 1;
+ tegra_soc_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+
+ case 0x03:
+ case 0x04:
+ tegra_cpu_speedo_id = 2;
+ tegra_soc_speedo_id = 1;
+ *threshold = THRESHOLD_INDEX_1;
+ break;
+
+ default:
+ pr_err("Tegra114 Unknown SKU %d\n", sku);
+ tegra_cpu_speedo_id = 0;
+ tegra_soc_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+ }
+
+ if (rev == TEGRA_REVISION_A01) {
+ tmp = tegra_fuse_readl(0x270) << 1;
+ tmp |= tegra_fuse_readl(0x26c);
+ if (!tmp)
+ tegra_cpu_speedo_id = 0;
+ }
+}
+
+void tegra114_init_speedo_data(void)
+{
+ u32 cpu_speedo_val;
+ u32 core_speedo_val;
+ int threshold;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+ rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold);
+
+ cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024;
+ core_speedo_val = tegra_fuse_readl(0x134);
+
+ for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++)
+ if (cpu_speedo_val < cpu_process_speedos[threshold][i])
+ break;
+ tegra_cpu_process_id = i;
+
+ for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++)
+ if (core_speedo_val < core_process_speedos[threshold][i])
+ break;
+ tegra_core_process_id = i;
+}
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/clocksource.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_data/clocksource-nomadik-mtu.h>
twd_local_timer = &u8500_twd_local_timer;
if (of_have_populated_dt())
- twd_local_timer_of_register();
+ clocksource_of_init();
else {
err = twd_local_timer_register(twd_local_timer);
if (err)
#include <linux/amba/bus.h>
#include <linux/amba/mmci.h>
#include <linux/io.h>
+#include <linux/clocksource.h>
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/irqchip.h>
#include <asm/arch_timer.h>
#include <asm/mach-types.h>
#include <asm/sizes.h>
-#include <asm/smp_twd.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
vexpress_clk_of_init();
+ clocksource_of_init();
do {
node = of_find_compatible_node(node, NULL, "arm,sp804");
} while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
irq_of_parse_and_map(node, 0));
}
- if (arch_timer_of_register() != 0)
- twd_local_timer_of_register();
+ arch_timer_of_register();
if (arch_timer_sched_clock_init() != 0)
versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
static LIST_HEAD(omap_timer_list);
static DEFINE_SPINLOCK(dm_timer_lock);
+enum {
+ REQUEST_ANY = 0,
+ REQUEST_BY_ID,
+ REQUEST_BY_CAP,
+ REQUEST_BY_NODE,
+};
+
/**
* omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
* @timer: timer pointer over which read operation to perform
return 0;
}
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
{
struct omap_dm_timer *timer = NULL, *t;
+ struct device_node *np = NULL;
unsigned long flags;
- int ret = 0;
+ u32 cap = 0;
+ int id = 0;
+
+ switch (req_type) {
+ case REQUEST_BY_ID:
+ id = *(int *)data;
+ break;
+ case REQUEST_BY_CAP:
+ cap = *(u32 *)data;
+ break;
+ case REQUEST_BY_NODE:
+ np = (struct device_node *)data;
+ break;
+ default:
+ /* REQUEST_ANY */
+ break;
+ }
spin_lock_irqsave(&dm_timer_lock, flags);
list_for_each_entry(t, &omap_timer_list, node) {
if (t->reserved)
continue;
- timer = t;
- timer->reserved = 1;
- break;
+ switch (req_type) {
+ case REQUEST_BY_ID:
+ if (id == t->pdev->id) {
+ timer = t;
+ timer->reserved = 1;
+ goto found;
+ }
+ break;
+ case REQUEST_BY_CAP:
+ if (cap == (t->capability & cap)) {
+ /*
+ * If timer is not NULL, we have already found
+ * one timer but it was not an exact match
+ * because it had more capabilites that what
+ * was required. Therefore, unreserve the last
+ * timer found and see if this one is a better
+ * match.
+ */
+ if (timer)
+ timer->reserved = 0;
+ timer = t;
+ timer->reserved = 1;
+
+ /* Exit loop early if we find an exact match */
+ if (t->capability == cap)
+ goto found;
+ }
+ break;
+ case REQUEST_BY_NODE:
+ if (np == t->pdev->dev.of_node) {
+ timer = t;
+ timer->reserved = 1;
+ goto found;
+ }
+ break;
+ default:
+ /* REQUEST_ANY */
+ timer = t;
+ timer->reserved = 1;
+ goto found;
+ }
}
+found:
spin_unlock_irqrestore(&dm_timer_lock, flags);
- if (timer) {
- ret = omap_dm_timer_prepare(timer);
- if (ret) {
- timer->reserved = 0;
- timer = NULL;
- }
+ if (timer && omap_dm_timer_prepare(timer)) {
+ timer->reserved = 0;
+ timer = NULL;
}
if (!timer)
return timer;
}
+
+struct omap_dm_timer *omap_dm_timer_request(void)
+{
+ return _omap_dm_timer_request(REQUEST_ANY, NULL);
+}
EXPORT_SYMBOL_GPL(omap_dm_timer_request);
struct omap_dm_timer *omap_dm_timer_request_specific(int id)
{
- struct omap_dm_timer *timer = NULL, *t;
- unsigned long flags;
- int ret = 0;
-
/* Requesting timer by ID is not supported when device tree is used */
if (of_have_populated_dt()) {
- pr_warn("%s: Please use omap_dm_timer_request_by_cap()\n",
+ pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
__func__);
return NULL;
}
- spin_lock_irqsave(&dm_timer_lock, flags);
- list_for_each_entry(t, &omap_timer_list, node) {
- if (t->pdev->id == id && !t->reserved) {
- timer = t;
- timer->reserved = 1;
- break;
- }
- }
- spin_unlock_irqrestore(&dm_timer_lock, flags);
-
- if (timer) {
- ret = omap_dm_timer_prepare(timer);
- if (ret) {
- timer->reserved = 0;
- timer = NULL;
- }
- }
-
- if (!timer)
- pr_debug("%s: timer%d request failed!\n", __func__, id);
-
- return timer;
+ return _omap_dm_timer_request(REQUEST_BY_ID, &id);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
*/
struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
{
- struct omap_dm_timer *timer = NULL, *t;
- unsigned long flags;
+ return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
- if (!cap)
+/**
+ * omap_dm_timer_request_by_node - Request a timer by device-tree node
+ * @np: Pointer to device-tree timer node
+ *
+ * Request a timer based upon a device node pointer. Returns pointer to
+ * timer handle on success and a NULL pointer on failure.
+ */
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+{
+ if (!np)
return NULL;
- spin_lock_irqsave(&dm_timer_lock, flags);
- list_for_each_entry(t, &omap_timer_list, node) {
- if ((!t->reserved) && ((t->capability & cap) == cap)) {
- /*
- * If timer is not NULL, we have already found one timer
- * but it was not an exact match because it had more
- * capabilites that what was required. Therefore,
- * unreserve the last timer found and see if this one
- * is a better match.
- */
- if (timer)
- timer->reserved = 0;
-
- timer = t;
- timer->reserved = 1;
-
- /* Exit loop early if we find an exact match */
- if (t->capability == cap)
- break;
- }
- }
- spin_unlock_irqrestore(&dm_timer_lock, flags);
-
- if (timer && omap_dm_timer_prepare(timer)) {
- timer->reserved = 0;
- timer = NULL;
- }
-
- if (!timer)
- pr_debug("%s: timer request failed!\n", __func__);
-
- return timer;
+ return _omap_dm_timer_request(REQUEST_BY_NODE, np);
}
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
int omap_dm_timer_free(struct omap_dm_timer *timer)
{
void omap_dm_timer_enable(struct omap_dm_timer *timer)
{
+ int c;
+
pm_runtime_get_sync(&timer->pdev->dev);
+
+ if (!(timer->capability & OMAP_TIMER_ALWON)) {
+ if (timer->get_context_loss_count) {
+ c = timer->get_context_loss_count(&timer->pdev->dev);
+ if (c != timer->ctx_loss_count) {
+ omap_timer_restore_context(timer);
+ timer->ctx_loss_count = c;
+ }
+ } else {
+ omap_timer_restore_context(timer);
+ }
+ }
}
EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
omap_dm_timer_enable(timer);
- if (!(timer->capability & OMAP_TIMER_ALWON)) {
- if (timer->get_context_loss_count &&
- timer->get_context_loss_count(&timer->pdev->dev) !=
- timer->ctx_loss_count)
- omap_timer_restore_context(timer);
- }
-
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (!(l & OMAP_TIMER_CTRL_ST)) {
l |= OMAP_TIMER_CTRL_ST;
__omap_dm_timer_stop(timer, timer->posted, rate);
- if (!(timer->capability & OMAP_TIMER_ALWON)) {
- if (timer->get_context_loss_count)
- timer->ctx_loss_count =
- timer->get_context_loss_count(&timer->pdev->dev);
- }
-
/*
* Since the register values are computed and written within
* __omap_dm_timer_stop, we need to use read to retrieve the
omap_dm_timer_enable(timer);
- if (!(timer->capability & OMAP_TIMER_ALWON)) {
- if (timer->get_context_loss_count &&
- timer->get_context_loss_count(&timer->pdev->dev) !=
- timer->ctx_loss_count)
- omap_timer_restore_context(timer);
- }
-
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload) {
l |= OMAP_TIMER_CTRL_AR;
}
EXPORT_SYMBOL_GPL(omap_dm_timers_active);
+static const struct of_device_id omap_timer_match[];
+
/**
* omap_dm_timer_probe - probe function called for every registered device
* @pdev: pointer to current timer platform device
struct omap_dm_timer *timer;
struct resource *mem, *irq;
struct device *dev = &pdev->dev;
- struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
+ const struct of_device_id *match;
+ const struct dmtimer_platform_data *pdata;
+
+ match = of_match_device(of_match_ptr(omap_timer_match), dev);
+ pdata = match ? match->data : dev->platform_data;
if (!pdata && !dev->of_node) {
dev_err(dev, "%s: no platform data.\n", __func__);
timer->capability |= OMAP_TIMER_SECURE;
} else {
timer->id = pdev->id;
- timer->errata = pdata->timer_errata;
timer->capability = pdata->timer_capability;
timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
timer->get_context_loss_count = pdata->get_context_loss_count;
}
+ if (pdata)
+ timer->errata = pdata->timer_errata;
+
timer->irq = irq->start;
timer->pdev = pdev;
return ret;
}
+static const struct dmtimer_platform_data omap3plus_pdata = {
+ .timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+};
+
static const struct of_device_id omap_timer_match[] = {
- { .compatible = "ti,omap2-timer", },
+ {
+ .compatible = "ti,omap2420-timer",
+ },
+ {
+ .compatible = "ti,omap3430-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,omap4430-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,omap5430-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,am335x-timer",
+ .data = &omap3plus_pdata,
+ },
+ {
+ .compatible = "ti,am335x-timer-1ms",
+ .data = &omap3plus_pdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, omap_timer_match);
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
int omap_dm_timer_free(struct omap_dm_timer *timer);
void omap_dm_timer_enable(struct omap_dm_timer *timer);
void omap_dm_timer_disable(struct omap_dm_timer *timer);
#
ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
-obj-y += addr-map.o
-
orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y)
+++ /dev/null
-/*
- * arch/arm/plat-orion/addr-map.c
- *
- * Address map functions for Marvell Orion based SoCs
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <plat/addr-map.h>
-
-struct mbus_dram_target_info orion_mbus_dram_info;
-
-const struct mbus_dram_target_info *mv_mbus_dram_info(void)
-{
- return &orion_mbus_dram_info;
-}
-EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
-
-/*
- * DDR target is the same on all Orion platforms.
- */
-#define TARGET_DDR 0
-
-/*
- * Helpers to get DDR bank info
- */
-#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
-#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
-
-/*
- * CPU Address Decode Windows registers
- */
-#define WIN_CTRL_OFF 0x0000
-#define WIN_BASE_OFF 0x0004
-#define WIN_REMAP_LO_OFF 0x0008
-#define WIN_REMAP_HI_OFF 0x000c
-
-#define ATTR_HW_COHERENCY (0x1 << 4)
-
-/*
- * Default implementation
- */
-static void __init __iomem *
-orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
-{
- return cfg->bridge_virt_base + (win << 4);
-}
-
-/*
- * Default implementation
- */
-static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
- const int win)
-{
- if (win < cfg->remappable_wins)
- return 1;
-
- return 0;
-}
-
-void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
- const int win, const u32 base,
- const u32 size, const u8 target,
- const u8 attr, const int remap)
-{
- void __iomem *addr = cfg->win_cfg_base(cfg, win);
- u32 ctrl, base_high, remap_addr;
-
- if (win >= cfg->num_wins) {
- printk(KERN_ERR "setup_cpu_win: trying to allocate window "
- "%d when only %d allowed\n", win, cfg->num_wins);
- }
-
- base_high = base & 0xffff0000;
- ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
-
- writel(base_high, addr + WIN_BASE_OFF);
- writel(ctrl, addr + WIN_CTRL_OFF);
- if (cfg->cpu_win_can_remap(cfg, win)) {
- if (remap < 0)
- remap_addr = base;
- else
- remap_addr = remap;
- writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF);
- writel(0, addr + WIN_REMAP_HI_OFF);
- }
-}
-
-/*
- * Configure a number of windows.
- */
-static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
- const struct orion_addr_map_info *info)
-{
- while (info->win != -1) {
- orion_setup_cpu_win(cfg, info->win, info->base, info->size,
- info->target, info->attr, info->remap);
- info++;
- }
-}
-
-static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg)
-{
- void __iomem *addr;
- int i;
-
- for (i = 0; i < cfg->num_wins; i++) {
- addr = cfg->win_cfg_base(cfg, i);
-
- writel(0, addr + WIN_BASE_OFF);
- writel(0, addr + WIN_CTRL_OFF);
- if (cfg->cpu_win_can_remap(cfg, i)) {
- writel(0, addr + WIN_REMAP_LO_OFF);
- writel(0, addr + WIN_REMAP_HI_OFF);
- }
- }
-}
-
-/*
- * Disable, clear and configure windows.
- */
-void __init orion_config_wins(struct orion_addr_map_cfg * cfg,
- const struct orion_addr_map_info *info)
-{
- if (!cfg->cpu_win_can_remap)
- cfg->cpu_win_can_remap = orion_cpu_win_can_remap;
-
- if (!cfg->win_cfg_base)
- cfg->win_cfg_base = orion_win_cfg_base;
-
- orion_disable_wins(cfg);
-
- if (info)
- orion_setup_cpu_wins(cfg, info);
-}
-
-/*
- * Setup MBUS dram target info.
- */
-void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
- const void __iomem *ddr_window_cpu_base)
-{
- int i;
- int cs;
-
- orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
-
- for (i = 0, cs = 0; i < 4; i++) {
- u32 base = readl(ddr_window_cpu_base + DDR_BASE_CS_OFF(i));
- u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
-
- /*
- * We only take care of entries for which the chip
- * select is enabled, and that don't have high base
- * address bits set (devices can only access the first
- * 32 bits of the memory).
- */
- if ((size & 1) && !(base & 0xF)) {
- struct mbus_dram_window *w;
-
- w = &orion_mbus_dram_info.cs[cs++];
- w->cs_index = i;
- w->mbus_attr = 0xf & ~(1 << i);
- if (cfg->hw_io_coherency)
- w->mbus_attr |= ATTR_HW_COHERENCY;
- w->base = base & 0xffff0000;
- w->size = (size | 0x0000ffff) + 1;
- }
- }
- orion_mbus_dram_info.num_cs = cs;
-}
}
}
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+ u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
+ int i;
+
+ out = readl_relaxed(GPIO_OUT(ochip));
+ io_conf = readl_relaxed(GPIO_IO_CONF(ochip));
+ blink = readl_relaxed(GPIO_BLINK_EN(ochip));
+ in_pol = readl_relaxed(GPIO_IN_POL(ochip));
+ data_in = readl_relaxed(GPIO_DATA_IN(ochip));
+ cause = readl_relaxed(GPIO_EDGE_CAUSE(ochip));
+ edg_msk = readl_relaxed(GPIO_EDGE_MASK(ochip));
+ lvl_msk = readl_relaxed(GPIO_LEVEL_MASK(ochip));
+
+ for (i = 0; i < chip->ngpio; i++) {
+ const char *label;
+ u32 msk;
+ bool is_out;
+
+ label = gpiochip_is_requested(chip, i);
+ if (!label)
+ continue;
+
+ msk = 1 << i;
+ is_out = !(io_conf & msk);
+
+ seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
+
+ if (is_out) {
+ seq_printf(s, " out %s %s\n",
+ out & msk ? "hi" : "lo",
+ blink & msk ? "(blink )" : "");
+ continue;
+ }
+
+ seq_printf(s, " in %s (act %s) - IRQ",
+ (data_in ^ in_pol) & msk ? "hi" : "lo",
+ in_pol & msk ? "lo" : "hi");
+ if (!((edg_msk | lvl_msk) & msk)) {
+ seq_printf(s, " disabled\n");
+ continue;
+ }
+ if (edg_msk & msk)
+ seq_printf(s, " edge ");
+ if (lvl_msk & msk)
+ seq_printf(s, " level");
+ seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear ");
+ }
+}
+#else
+#define orion_gpio_dbg_show NULL
+#endif
+
void __init orion_gpio_init(struct device_node *np,
int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
#ifdef CONFIG_OF
ochip->chip.of_node = np;
#endif
+ ochip->chip.dbg_show = orion_gpio_dbg_show;
spin_lock_init(&ochip->lock);
ochip->base = (void __iomem *)base;
* BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
* WIN[0-3] -> DRAM bank[0-3]
*/
-static void __init orion_pcie_setup_wins(void __iomem *base,
- struct mbus_dram_target_info *dram)
+static void __init orion_pcie_setup_wins(void __iomem *base)
{
+ const struct mbus_dram_target_info *dram;
u32 size;
int i;
+ dram = mv_mbus_dram_info();
+
/*
* First, disable and clear BARs and windows.
*/
*/
size = 0;
for (i = 0; i < dram->num_cs; i++) {
- struct mbus_dram_window *cs = dram->cs + i;
+ const struct mbus_dram_window *cs = dram->cs + i;
writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i));
writel(0, base + PCIE_WIN04_REMAP_OFF(i));
/*
* Point PCIe unit MBUS decode windows to DRAM space.
*/
- orion_pcie_setup_wins(base, &orion_mbus_dram_info);
+ orion_pcie_setup_wins(base);
/*
* Master + slave enable.
menu "Bus devices"
+config MVEBU_MBUS
+ bool
+ depends on PLAT_ORION
+ help
+ Driver needed for the MBus configuration on Marvell EBU SoCs
+ (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
+
config OMAP_OCP2SCP
tristate "OMAP OCP2SCP DRIVER"
depends on ARCH_OMAP2PLUS
# Makefile for the bus drivers.
#
+obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
# Interconnect bus driver for OMAP SoCs.
--- /dev/null
+/*
+ * Address map functions for Marvell EBU SoCs (Kirkwood, Armada
+ * 370/XP, Dove, Orion5x and MV78xx0)
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The Marvell EBU SoCs have a configurable physical address space:
+ * the physical address at which certain devices (PCIe, NOR, NAND,
+ * etc.) sit can be configured. The configuration takes place through
+ * two sets of registers:
+ *
+ * - One to configure the access of the CPU to the devices. Depending
+ * on the families, there are between 8 and 20 configurable windows,
+ * each can be use to create a physical memory window that maps to a
+ * specific device. Devices are identified by a tuple (target,
+ * attribute).
+ *
+ * - One to configure the access to the CPU to the SDRAM. There are
+ * either 2 (for Dove) or 4 (for other families) windows to map the
+ * SDRAM into the physical address space.
+ *
+ * This driver:
+ *
+ * - Reads out the SDRAM address decoding windows at initialization
+ * time, and fills the mvebu_mbus_dram_info structure with these
+ * informations. The exported function mv_mbus_dram_info() allow
+ * device drivers to get those informations related to the SDRAM
+ * address decoding windows. This is because devices also have their
+ * own windows (configured through registers that are part of each
+ * device register space), and therefore the drivers for Marvell
+ * devices have to configure those device -> SDRAM windows to ensure
+ * that DMA works properly.
+ *
+ * - Provides an API for platform code or device drivers to
+ * dynamically add or remove address decoding windows for the CPU ->
+ * device accesses. This API is mvebu_mbus_add_window(),
+ * mvebu_mbus_add_window_remap_flags() and
+ * mvebu_mbus_del_window(). Since the (target, attribute) values
+ * differ from one SoC family to another, the API uses a 'const char
+ * *' string to identify devices, and this driver is responsible for
+ * knowing the mapping between the name of a device and its
+ * corresponding (target, attribute) in the current SoC family.
+ *
+ * - Provides a debugfs interface in /sys/kernel/debug/mvebu-mbus/ to
+ * see the list of CPU -> SDRAM windows and their configuration
+ * (file 'sdram') and the list of CPU -> devices windows and their
+ * configuration (file 'devices').
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/debugfs.h>
+
+/*
+ * DDR target is the same on all platforms.
+ */
+#define TARGET_DDR 0
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN_CTRL_OFF 0x0000
+#define WIN_CTRL_ENABLE BIT(0)
+#define WIN_CTRL_TGT_MASK 0xf0
+#define WIN_CTRL_TGT_SHIFT 4
+#define WIN_CTRL_ATTR_MASK 0xff00
+#define WIN_CTRL_ATTR_SHIFT 8
+#define WIN_CTRL_SIZE_MASK 0xffff0000
+#define WIN_CTRL_SIZE_SHIFT 16
+#define WIN_BASE_OFF 0x0004
+#define WIN_BASE_LOW 0xffff0000
+#define WIN_BASE_HIGH 0xf
+#define WIN_REMAP_LO_OFF 0x0008
+#define WIN_REMAP_LOW 0xffff0000
+#define WIN_REMAP_HI_OFF 0x000c
+
+#define ATTR_HW_COHERENCY (0x1 << 4)
+
+#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
+#define DDR_BASE_CS_HIGH_MASK 0xf
+#define DDR_BASE_CS_LOW_MASK 0xff000000
+#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
+#define DDR_SIZE_ENABLED BIT(0)
+#define DDR_SIZE_CS_MASK 0x1c
+#define DDR_SIZE_CS_SHIFT 2
+#define DDR_SIZE_MASK 0xff000000
+
+#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
+
+struct mvebu_mbus_mapping {
+ const char *name;
+ u8 target;
+ u8 attr;
+ u8 attrmask;
+};
+
+/*
+ * Masks used for the 'attrmask' field of mvebu_mbus_mapping. They
+ * allow to get the real attribute value, discarding the special bits
+ * used to select a PCI MEM region or a PCI WA region. This allows the
+ * debugfs code to reverse-match the name of a device from its
+ * target/attr values.
+ *
+ * For all devices except PCI, all bits of 'attr' must be
+ * considered. For most SoCs, only bit 3 should be ignored (it allows
+ * to select between PCI MEM and PCI I/O). On Orion5x however, there
+ * is the special bit 5 to select a PCI WA region.
+ */
+#define MAPDEF_NOMASK 0xff
+#define MAPDEF_PCIMASK 0xf7
+#define MAPDEF_ORIONPCIMASK 0xd7
+
+/* Macro used to define one mvebu_mbus_mapping entry */
+#define MAPDEF(__n, __t, __a, __m) \
+ { .name = __n, .target = __t, .attr = __a, .attrmask = __m }
+
+struct mvebu_mbus_state;
+
+struct mvebu_mbus_soc_data {
+ unsigned int num_wins;
+ unsigned int num_remappable_wins;
+ unsigned int (*win_cfg_offset)(const int win);
+ void (*setup_cpu_target)(struct mvebu_mbus_state *s);
+ int (*show_cpu_target)(struct mvebu_mbus_state *s,
+ struct seq_file *seq, void *v);
+ const struct mvebu_mbus_mapping *map;
+};
+
+struct mvebu_mbus_state {
+ void __iomem *mbuswins_base;
+ void __iomem *sdramwins_base;
+ struct dentry *debugfs_root;
+ struct dentry *debugfs_sdram;
+ struct dentry *debugfs_devs;
+ const struct mvebu_mbus_soc_data *soc;
+ int hw_io_coherency;
+};
+
+static struct mvebu_mbus_state mbus_state;
+
+static struct mbus_dram_target_info mvebu_mbus_dram_info;
+const struct mbus_dram_target_info *mv_mbus_dram_info(void)
+{
+ return &mvebu_mbus_dram_info;
+}
+EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
+
+/*
+ * Functions to manipulate the address decoding windows
+ */
+
+static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus,
+ int win, int *enabled, u64 *base,
+ u32 *size, u8 *target, u8 *attr,
+ u64 *remap)
+{
+ void __iomem *addr = mbus->mbuswins_base +
+ mbus->soc->win_cfg_offset(win);
+ u32 basereg = readl(addr + WIN_BASE_OFF);
+ u32 ctrlreg = readl(addr + WIN_CTRL_OFF);
+
+ if (!(ctrlreg & WIN_CTRL_ENABLE)) {
+ *enabled = 0;
+ return;
+ }
+
+ *enabled = 1;
+ *base = ((u64)basereg & WIN_BASE_HIGH) << 32;
+ *base |= (basereg & WIN_BASE_LOW);
+ *size = (ctrlreg | ~WIN_CTRL_SIZE_MASK) + 1;
+
+ if (target)
+ *target = (ctrlreg & WIN_CTRL_TGT_MASK) >> WIN_CTRL_TGT_SHIFT;
+
+ if (attr)
+ *attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT;
+
+ if (remap) {
+ if (win < mbus->soc->num_remappable_wins) {
+ u32 remap_low = readl(addr + WIN_REMAP_LO_OFF);
+ u32 remap_hi = readl(addr + WIN_REMAP_HI_OFF);
+ *remap = ((u64)remap_hi << 32) | remap_low;
+ } else
+ *remap = 0;
+ }
+}
+
+static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
+ int win)
+{
+ void __iomem *addr;
+
+ addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win);
+
+ writel(0, addr + WIN_BASE_OFF);
+ writel(0, addr + WIN_CTRL_OFF);
+ if (win < mbus->soc->num_remappable_wins) {
+ writel(0, addr + WIN_REMAP_LO_OFF);
+ writel(0, addr + WIN_REMAP_HI_OFF);
+ }
+}
+
+/* Checks whether the given window number is available */
+static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
+ const int win)
+{
+ void __iomem *addr = mbus->mbuswins_base +
+ mbus->soc->win_cfg_offset(win);
+ u32 ctrl = readl(addr + WIN_CTRL_OFF);
+ return !(ctrl & WIN_CTRL_ENABLE);
+}
+
+/*
+ * Checks whether the given (base, base+size) area doesn't overlap an
+ * existing region
+ */
+static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
+ phys_addr_t base, size_t size,
+ u8 target, u8 attr)
+{
+ u64 end = (u64)base + size;
+ int win;
+
+ for (win = 0; win < mbus->soc->num_wins; win++) {
+ u64 wbase, wend;
+ u32 wsize;
+ u8 wtarget, wattr;
+ int enabled;
+
+ mvebu_mbus_read_window(mbus, win,
+ &enabled, &wbase, &wsize,
+ &wtarget, &wattr, NULL);
+
+ if (!enabled)
+ continue;
+
+ wend = wbase + wsize;
+
+ /*
+ * Check if the current window overlaps with the
+ * proposed physical range
+ */
+ if ((u64)base < wend && end > wbase)
+ return 0;
+
+ /*
+ * Check if target/attribute conflicts
+ */
+ if (target == wtarget && attr == wattr)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus,
+ phys_addr_t base, size_t size)
+{
+ int win;
+
+ for (win = 0; win < mbus->soc->num_wins; win++) {
+ u64 wbase;
+ u32 wsize;
+ int enabled;
+
+ mvebu_mbus_read_window(mbus, win,
+ &enabled, &wbase, &wsize,
+ NULL, NULL, NULL);
+
+ if (!enabled)
+ continue;
+
+ if (base == wbase && size == wsize)
+ return win;
+ }
+
+ return -ENODEV;
+}
+
+static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
+ int win, phys_addr_t base, size_t size,
+ phys_addr_t remap, u8 target,
+ u8 attr)
+{
+ void __iomem *addr = mbus->mbuswins_base +
+ mbus->soc->win_cfg_offset(win);
+ u32 ctrl, remap_addr;
+
+ ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
+ (attr << WIN_CTRL_ATTR_SHIFT) |
+ (target << WIN_CTRL_TGT_SHIFT) |
+ WIN_CTRL_ENABLE;
+
+ writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
+ writel(ctrl, addr + WIN_CTRL_OFF);
+ if (win < mbus->soc->num_remappable_wins) {
+ if (remap == MVEBU_MBUS_NO_REMAP)
+ remap_addr = base;
+ else
+ remap_addr = remap;
+ writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF);
+ writel(0, addr + WIN_REMAP_HI_OFF);
+ }
+
+ return 0;
+}
+
+static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus,
+ phys_addr_t base, size_t size,
+ phys_addr_t remap, u8 target,
+ u8 attr)
+{
+ int win;
+
+ if (remap == MVEBU_MBUS_NO_REMAP) {
+ for (win = mbus->soc->num_remappable_wins;
+ win < mbus->soc->num_wins; win++)
+ if (mvebu_mbus_window_is_free(mbus, win))
+ return mvebu_mbus_setup_window(mbus, win, base,
+ size, remap,
+ target, attr);
+ }
+
+
+ for (win = 0; win < mbus->soc->num_wins; win++)
+ if (mvebu_mbus_window_is_free(mbus, win))
+ return mvebu_mbus_setup_window(mbus, win, base, size,
+ remap, target, attr);
+
+ return -ENOMEM;
+}
+
+/*
+ * Debugfs debugging
+ */
+
+/* Common function used for Dove, Kirkwood, Armada 370/XP and Orion 5x */
+static int mvebu_sdram_debug_show_orion(struct mvebu_mbus_state *mbus,
+ struct seq_file *seq, void *v)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ u32 basereg = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
+ u32 sizereg = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+ u64 base;
+ u32 size;
+
+ if (!(sizereg & DDR_SIZE_ENABLED)) {
+ seq_printf(seq, "[%d] disabled\n", i);
+ continue;
+ }
+
+ base = ((u64)basereg & DDR_BASE_CS_HIGH_MASK) << 32;
+ base |= basereg & DDR_BASE_CS_LOW_MASK;
+ size = (sizereg | ~DDR_SIZE_MASK);
+
+ seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
+ i, (unsigned long long)base,
+ (unsigned long long)base + size + 1,
+ (sizereg & DDR_SIZE_CS_MASK) >> DDR_SIZE_CS_SHIFT);
+ }
+
+ return 0;
+}
+
+/* Special function for Dove */
+static int mvebu_sdram_debug_show_dove(struct mvebu_mbus_state *mbus,
+ struct seq_file *seq, void *v)
+{
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
+ u64 base;
+ u32 size;
+
+ if (!(map & 1)) {
+ seq_printf(seq, "[%d] disabled\n", i);
+ continue;
+ }
+
+ base = map & 0xff800000;
+ size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+
+ seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
+ i, (unsigned long long)base,
+ (unsigned long long)base + size, i);
+ }
+
+ return 0;
+}
+
+static int mvebu_sdram_debug_show(struct seq_file *seq, void *v)
+{
+ struct mvebu_mbus_state *mbus = &mbus_state;
+ return mbus->soc->show_cpu_target(mbus, seq, v);
+}
+
+static int mvebu_sdram_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mvebu_sdram_debug_show, inode->i_private);
+}
+
+static const struct file_operations mvebu_sdram_debug_fops = {
+ .open = mvebu_sdram_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
+{
+ struct mvebu_mbus_state *mbus = &mbus_state;
+ int win;
+
+ for (win = 0; win < mbus->soc->num_wins; win++) {
+ u64 wbase, wremap;
+ u32 wsize;
+ u8 wtarget, wattr;
+ int enabled, i;
+ const char *name;
+
+ mvebu_mbus_read_window(mbus, win,
+ &enabled, &wbase, &wsize,
+ &wtarget, &wattr, &wremap);
+
+ if (!enabled) {
+ seq_printf(seq, "[%02d] disabled\n", win);
+ continue;
+ }
+
+
+ for (i = 0; mbus->soc->map[i].name; i++)
+ if (mbus->soc->map[i].target == wtarget &&
+ mbus->soc->map[i].attr ==
+ (wattr & mbus->soc->map[i].attrmask))
+ break;
+
+ name = mbus->soc->map[i].name ?: "unknown";
+
+ seq_printf(seq, "[%02d] %016llx - %016llx : %s",
+ win, (unsigned long long)wbase,
+ (unsigned long long)(wbase + wsize), name);
+
+ if (win < mbus->soc->num_remappable_wins) {
+ seq_printf(seq, " (remap %016llx)\n",
+ (unsigned long long)wremap);
+ } else
+ seq_printf(seq, "\n");
+ }
+
+ return 0;
+}
+
+static int mvebu_devs_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mvebu_devs_debug_show, inode->i_private);
+}
+
+static const struct file_operations mvebu_devs_debug_fops = {
+ .open = mvebu_devs_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/*
+ * SoC-specific functions and definitions
+ */
+
+static unsigned int orion_mbus_win_offset(int win)
+{
+ return win << 4;
+}
+
+static unsigned int armada_370_xp_mbus_win_offset(int win)
+{
+ /* The register layout is a bit annoying and the below code
+ * tries to cope with it.
+ * - At offset 0x0, there are the registers for the first 8
+ * windows, with 4 registers of 32 bits per window (ctrl,
+ * base, remap low, remap high)
+ * - Then at offset 0x80, there is a hole of 0x10 bytes for
+ * the internal registers base address and internal units
+ * sync barrier register.
+ * - Then at offset 0x90, there the registers for 12
+ * windows, with only 2 registers of 32 bits per window
+ * (ctrl, base).
+ */
+ if (win < 8)
+ return win << 4;
+ else
+ return 0x90 + ((win - 8) << 3);
+}
+
+static unsigned int mv78xx0_mbus_win_offset(int win)
+{
+ if (win < 8)
+ return win << 4;
+ else
+ return 0x900 + ((win - 8) << 4);
+}
+
+static void __init
+mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
+{
+ int i;
+ int cs;
+
+ mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ for (i = 0, cs = 0; i < 4; i++) {
+ u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
+ u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+
+ /*
+ * We only take care of entries for which the chip
+ * select is enabled, and that don't have high base
+ * address bits set (devices can only access the first
+ * 32 bits of the memory).
+ */
+ if ((size & DDR_SIZE_ENABLED) &&
+ !(base & DDR_BASE_CS_HIGH_MASK)) {
+ struct mbus_dram_window *w;
+
+ w = &mvebu_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0xf & ~(1 << i);
+ if (mbus->hw_io_coherency)
+ w->mbus_attr |= ATTR_HW_COHERENCY;
+ w->base = base & DDR_BASE_CS_LOW_MASK;
+ w->size = (size | ~DDR_SIZE_MASK) + 1;
+ }
+ }
+ mvebu_mbus_dram_info.num_cs = cs;
+}
+
+static void __init
+mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
+{
+ int i;
+ int cs;
+
+ mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ for (i = 0, cs = 0; i < 2; i++) {
+ u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
+
+ /*
+ * Chip select enabled?
+ */
+ if (map & 1) {
+ struct mbus_dram_window *w;
+
+ w = &mvebu_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0; /* CS address decoding done inside */
+ /* the DDR controller, no need to */
+ /* provide attributes */
+ w->base = map & 0xff800000;
+ w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+ }
+ }
+
+ mvebu_mbus_dram_info.num_cs = cs;
+}
+
+static const struct mvebu_mbus_mapping armada_370_map[] = {
+ MAPDEF("bootrom", 1, 0xe0, MAPDEF_NOMASK),
+ MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
+ MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
+ {},
+};
+
+static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
+ .num_wins = 20,
+ .num_remappable_wins = 8,
+ .win_cfg_offset = armada_370_xp_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
+ .map = armada_370_map,
+};
+
+static const struct mvebu_mbus_mapping armada_xp_map[] = {
+ MAPDEF("bootrom", 1, 0x1d, MAPDEF_NOMASK),
+ MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
+ MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
+ MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
+ MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
+ MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
+ MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
+ {},
+};
+
+static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
+ .num_wins = 20,
+ .num_remappable_wins = 8,
+ .win_cfg_offset = armada_370_xp_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
+ .map = armada_xp_map,
+};
+
+static const struct mvebu_mbus_mapping kirkwood_map[] = {
+ MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.0", 4, 0xd0, MAPDEF_PCIMASK),
+ MAPDEF("sram", 3, 0x01, MAPDEF_NOMASK),
+ MAPDEF("nand", 1, 0x2f, MAPDEF_NOMASK),
+ {},
+};
+
+static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
+ .num_wins = 8,
+ .num_remappable_wins = 4,
+ .win_cfg_offset = orion_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
+ .map = kirkwood_map,
+};
+
+static const struct mvebu_mbus_mapping dove_map[] = {
+ MAPDEF("pcie0.0", 0x4, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.0", 0x8, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("cesa", 0x3, 0x01, MAPDEF_NOMASK),
+ MAPDEF("bootrom", 0x1, 0xfd, MAPDEF_NOMASK),
+ MAPDEF("scratchpad", 0xd, 0x0, MAPDEF_NOMASK),
+ {},
+};
+
+static const struct mvebu_mbus_soc_data dove_mbus_data = {
+ .num_wins = 8,
+ .num_remappable_wins = 4,
+ .win_cfg_offset = orion_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_dove,
+ .map = dove_map,
+};
+
+static const struct mvebu_mbus_mapping orion5x_map[] = {
+ MAPDEF("pcie0.0", 4, 0x51, MAPDEF_ORIONPCIMASK),
+ MAPDEF("pci0.0", 3, 0x51, MAPDEF_ORIONPCIMASK),
+ MAPDEF("devbus-boot", 1, 0x0f, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs0", 1, 0x1e, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs1", 1, 0x1d, MAPDEF_NOMASK),
+ MAPDEF("devbus-cs2", 1, 0x1b, MAPDEF_NOMASK),
+ MAPDEF("sram", 0, 0x00, MAPDEF_NOMASK),
+ {},
+};
+
+/*
+ * Some variants of Orion5x have 4 remappable windows, some other have
+ * only two of them.
+ */
+static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
+ .num_wins = 8,
+ .num_remappable_wins = 4,
+ .win_cfg_offset = orion_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
+ .map = orion5x_map,
+};
+
+static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
+ .num_wins = 8,
+ .num_remappable_wins = 2,
+ .win_cfg_offset = orion_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
+ .map = orion5x_map,
+};
+
+static const struct mvebu_mbus_mapping mv78xx0_map[] = {
+ MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
+ MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
+ MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
+ MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
+ MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
+ MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
+ {},
+};
+
+static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
+ .num_wins = 14,
+ .num_remappable_wins = 8,
+ .win_cfg_offset = mv78xx0_mbus_win_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
+ .map = mv78xx0_map,
+};
+
+/*
+ * The driver doesn't yet have a DT binding because the details of
+ * this DT binding still need to be sorted out. However, as a
+ * preparation, we already use of_device_id to match a SoC description
+ * string against the SoC specific details of this driver.
+ */
+static const struct of_device_id of_mvebu_mbus_ids[] = {
+ { .compatible = "marvell,armada370-mbus",
+ .data = &armada_370_mbus_data, },
+ { .compatible = "marvell,armadaxp-mbus",
+ .data = &armada_xp_mbus_data, },
+ { .compatible = "marvell,kirkwood-mbus",
+ .data = &kirkwood_mbus_data, },
+ { .compatible = "marvell,dove-mbus",
+ .data = &dove_mbus_data, },
+ { .compatible = "marvell,orion5x-88f5281-mbus",
+ .data = &orion5x_4win_mbus_data, },
+ { .compatible = "marvell,orion5x-88f5182-mbus",
+ .data = &orion5x_2win_mbus_data, },
+ { .compatible = "marvell,orion5x-88f5181-mbus",
+ .data = &orion5x_2win_mbus_data, },
+ { .compatible = "marvell,orion5x-88f6183-mbus",
+ .data = &orion5x_4win_mbus_data, },
+ { .compatible = "marvell,mv78xx0-mbus",
+ .data = &mv78xx0_mbus_data, },
+ { },
+};
+
+/*
+ * Public API of the driver
+ */
+int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
+ size_t size, phys_addr_t remap,
+ unsigned int flags)
+{
+ struct mvebu_mbus_state *s = &mbus_state;
+ u8 target, attr;
+ int i;
+
+ if (!s->soc->map)
+ return -ENODEV;
+
+ for (i = 0; s->soc->map[i].name; i++)
+ if (!strcmp(s->soc->map[i].name, devname))
+ break;
+
+ if (!s->soc->map[i].name) {
+ pr_err("mvebu-mbus: unknown device '%s'\n", devname);
+ return -ENODEV;
+ }
+
+ target = s->soc->map[i].target;
+ attr = s->soc->map[i].attr;
+
+ if (flags == MVEBU_MBUS_PCI_MEM)
+ attr |= 0x8;
+ else if (flags == MVEBU_MBUS_PCI_WA)
+ attr |= 0x28;
+
+ if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
+ pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
+ devname);
+ return -EINVAL;
+ }
+
+ return mvebu_mbus_alloc_window(s, base, size, remap, target, attr);
+
+}
+
+int mvebu_mbus_add_window(const char *devname, phys_addr_t base, size_t size)
+{
+ return mvebu_mbus_add_window_remap_flags(devname, base, size,
+ MVEBU_MBUS_NO_REMAP, 0);
+}
+
+int mvebu_mbus_del_window(phys_addr_t base, size_t size)
+{
+ int win;
+
+ win = mvebu_mbus_find_window(&mbus_state, base, size);
+ if (win < 0)
+ return win;
+
+ mvebu_mbus_disable_window(&mbus_state, win);
+ return 0;
+}
+
+static __init int mvebu_mbus_debugfs_init(void)
+{
+ struct mvebu_mbus_state *s = &mbus_state;
+
+ /*
+ * If no base has been initialized, doesn't make sense to
+ * register the debugfs entries. We may be on a multiplatform
+ * kernel that isn't running a Marvell EBU SoC.
+ */
+ if (!s->mbuswins_base)
+ return 0;
+
+ s->debugfs_root = debugfs_create_dir("mvebu-mbus", NULL);
+ if (s->debugfs_root) {
+ s->debugfs_sdram = debugfs_create_file("sdram", S_IRUGO,
+ s->debugfs_root, NULL,
+ &mvebu_sdram_debug_fops);
+ s->debugfs_devs = debugfs_create_file("devices", S_IRUGO,
+ s->debugfs_root, NULL,
+ &mvebu_devs_debug_fops);
+ }
+
+ return 0;
+}
+fs_initcall(mvebu_mbus_debugfs_init);
+
+int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
+ size_t mbuswins_size,
+ phys_addr_t sdramwins_phys_base,
+ size_t sdramwins_size)
+{
+ struct mvebu_mbus_state *mbus = &mbus_state;
+ const struct of_device_id *of_id;
+ int win;
+
+ for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
+ if (!strcmp(of_id->compatible, soc))
+ break;
+
+ if (!of_id->compatible) {
+ pr_err("mvebu-mbus: could not find a matching SoC family\n");
+ return -ENODEV;
+ }
+
+ mbus->soc = of_id->data;
+
+ mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size);
+ if (!mbus->mbuswins_base)
+ return -ENOMEM;
+
+ mbus->sdramwins_base = ioremap(sdramwins_phys_base, sdramwins_size);
+ if (!mbus->sdramwins_base) {
+ iounmap(mbus_state.mbuswins_base);
+ return -ENOMEM;
+ }
+
+ if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
+ mbus->hw_io_coherency = 1;
+
+ for (win = 0; win < mbus->soc->num_wins; win++)
+ mvebu_mbus_disable_window(mbus, win);
+
+ mbus->soc->setup_cpu_target(mbus);
+
+ return 0;
+}
McPDM. McPDM module is using the external bit clock on the McPDM bus
as functional clock.
+config COMMON_CLK_AXI_CLKGEN
+ tristate "AXI clkgen driver"
+ depends on ARCH_ZYNQ || MICROBLAZE
+ help
+ ---help---
+ Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
+ FPGAs. It is commonly used in Analog Devices' reference designs.
+
endmenu
source "drivers/clk/mvebu/Kconfig"
obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
obj-$(CONFIG_COMMON_CLK) += clk-gate.o
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
+obj-$(CONFIG_COMMON_CLK) += clk-composite.o
# SoCs specific
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
+obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o
obj-$(CONFIG_X86) += x86/
# Chip specific
+obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
--- /dev/null
+/*
+ * AXI clkgen driver
+ *
+ * Copyright 2012-2013 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#define AXI_CLKGEN_REG_UPDATE_ENABLE 0x04
+#define AXI_CLKGEN_REG_CLK_OUT1 0x08
+#define AXI_CLKGEN_REG_CLK_OUT2 0x0c
+#define AXI_CLKGEN_REG_CLK_DIV 0x10
+#define AXI_CLKGEN_REG_CLK_FB1 0x14
+#define AXI_CLKGEN_REG_CLK_FB2 0x18
+#define AXI_CLKGEN_REG_LOCK1 0x1c
+#define AXI_CLKGEN_REG_LOCK2 0x20
+#define AXI_CLKGEN_REG_LOCK3 0x24
+#define AXI_CLKGEN_REG_FILTER1 0x28
+#define AXI_CLKGEN_REG_FILTER2 0x2c
+
+struct axi_clkgen {
+ void __iomem *base;
+ struct clk_hw clk_hw;
+};
+
+static uint32_t axi_clkgen_lookup_filter(unsigned int m)
+{
+ switch (m) {
+ case 0:
+ return 0x01001990;
+ case 1:
+ return 0x01001190;
+ case 2:
+ return 0x01009890;
+ case 3:
+ return 0x01001890;
+ case 4:
+ return 0x01008890;
+ case 5 ... 8:
+ return 0x01009090;
+ case 9 ... 11:
+ return 0x01000890;
+ case 12:
+ return 0x08009090;
+ case 13 ... 22:
+ return 0x01001090;
+ case 23 ... 36:
+ return 0x01008090;
+ case 37 ... 46:
+ return 0x08001090;
+ default:
+ return 0x08008090;
+ }
+}
+
+static const uint32_t axi_clkgen_lock_table[] = {
+ 0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8,
+ 0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8,
+ 0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339,
+ 0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271,
+ 0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4,
+ 0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190,
+ 0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e,
+ 0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c,
+ 0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113,
+};
+
+static uint32_t axi_clkgen_lookup_lock(unsigned int m)
+{
+ if (m < ARRAY_SIZE(axi_clkgen_lock_table))
+ return axi_clkgen_lock_table[m];
+ return 0x1f1f00fa;
+}
+
+static const unsigned int fpfd_min = 10000;
+static const unsigned int fpfd_max = 300000;
+static const unsigned int fvco_min = 600000;
+static const unsigned int fvco_max = 1200000;
+
+static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
+ unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout)
+{
+ unsigned long d, d_min, d_max, _d_min, _d_max;
+ unsigned long m, m_min, m_max;
+ unsigned long f, dout, best_f, fvco;
+
+ fin /= 1000;
+ fout /= 1000;
+
+ best_f = ULONG_MAX;
+ *best_d = 0;
+ *best_m = 0;
+ *best_dout = 0;
+
+ d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1);
+ d_max = min_t(unsigned long, fin / fpfd_min, 80);
+
+ m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1);
+ m_max = min_t(unsigned long, fvco_max * d_max / fin, 64);
+
+ for (m = m_min; m <= m_max; m++) {
+ _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max));
+ _d_max = min(d_max, fin * m / fvco_min);
+
+ for (d = _d_min; d <= _d_max; d++) {
+ fvco = fin * m / d;
+
+ dout = DIV_ROUND_CLOSEST(fvco, fout);
+ dout = clamp_t(unsigned long, dout, 1, 128);
+ f = fvco / dout;
+ if (abs(f - fout) < abs(best_f - fout)) {
+ best_f = f;
+ *best_d = d;
+ *best_m = m;
+ *best_dout = dout;
+ if (best_f == fout)
+ return;
+ }
+ }
+ }
+}
+
+static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low,
+ unsigned int *high, unsigned int *edge, unsigned int *nocount)
+{
+ if (divider == 1)
+ *nocount = 1;
+ else
+ *nocount = 0;
+
+ *high = divider / 2;
+ *edge = divider % 2;
+ *low = divider - *high;
+}
+
+static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
+ unsigned int reg, unsigned int val)
+{
+ writel(val, axi_clkgen->base + reg);
+}
+
+static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
+ unsigned int reg, unsigned int *val)
+{
+ *val = readl(axi_clkgen->base + reg);
+}
+
+static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
+{
+ return container_of(clk_hw, struct axi_clkgen, clk_hw);
+}
+
+static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
+ unsigned long rate, unsigned long parent_rate)
+{
+ struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+ unsigned int d, m, dout;
+ unsigned int nocount;
+ unsigned int high;
+ unsigned int edge;
+ unsigned int low;
+ uint32_t filter;
+ uint32_t lock;
+
+ if (parent_rate == 0 || rate == 0)
+ return -EINVAL;
+
+ axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout);
+
+ if (d == 0 || dout == 0 || m == 0)
+ return -EINVAL;
+
+ filter = axi_clkgen_lookup_filter(m - 1);
+ lock = axi_clkgen_lookup_lock(m - 1);
+
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0);
+
+ axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1,
+ (high << 6) | low);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2,
+ (edge << 7) | (nocount << 6));
+
+ axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV,
+ (edge << 13) | (nocount << 12) | (high << 6) | low);
+
+ axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1,
+ (high << 6) | low);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2,
+ (edge << 7) | (nocount << 6));
+
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2,
+ (((lock >> 16) & 0x1f) << 10) | 0x1);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3,
+ (((lock >> 24) & 0x1f) << 10) | 0x3e9);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter);
+
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1);
+
+ return 0;
+}
+
+static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned int d, m, dout;
+
+ axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout);
+
+ if (d == 0 || dout == 0 || m == 0)
+ return -EINVAL;
+
+ return *parent_rate / d * m / dout;
+}
+
+static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
+ unsigned long parent_rate)
+{
+ struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+ unsigned int d, m, dout;
+ unsigned int reg;
+ unsigned long long tmp;
+
+ axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, ®);
+ dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, ®);
+ d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, ®);
+ m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+
+ if (d == 0 || dout == 0)
+ return 0;
+
+ tmp = (unsigned long long)(parent_rate / d) * m;
+ do_div(tmp, dout);
+
+ if (tmp > ULONG_MAX)
+ return ULONG_MAX;
+
+ return tmp;
+}
+
+static const struct clk_ops axi_clkgen_ops = {
+ .recalc_rate = axi_clkgen_recalc_rate,
+ .round_rate = axi_clkgen_round_rate,
+ .set_rate = axi_clkgen_set_rate,
+};
+
+static int axi_clkgen_probe(struct platform_device *pdev)
+{
+ struct axi_clkgen *axi_clkgen;
+ struct clk_init_data init;
+ const char *parent_name;
+ const char *clk_name;
+ struct resource *mem;
+ struct clk *clk;
+
+ axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
+ if (!axi_clkgen)
+ return -ENOMEM;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(axi_clkgen->base))
+ return PTR_ERR(axi_clkgen->base);
+
+ parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
+ if (!parent_name)
+ return -EINVAL;
+
+ clk_name = pdev->dev.of_node->name;
+ of_property_read_string(pdev->dev.of_node, "clock-output-names",
+ &clk_name);
+
+ init.name = clk_name;
+ init.ops = &axi_clkgen_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ axi_clkgen->clk_hw.init = &init;
+ clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get,
+ clk);
+}
+
+static int axi_clkgen_remove(struct platform_device *pdev)
+{
+ of_clk_del_provider(pdev->dev.of_node);
+
+ return 0;
+}
+
+static const struct of_device_id axi_clkgen_ids[] = {
+ { .compatible = "adi,axi-clkgen-1.00.a" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
+
+static struct platform_driver axi_clkgen_driver = {
+ .driver = {
+ .name = "adi-axi-clkgen",
+ .owner = THIS_MODULE,
+ .of_match_table = axi_clkgen_ids,
+ },
+ .probe = axi_clkgen_probe,
+ .remove = axi_clkgen_remove,
+};
+module_platform_driver(axi_clkgen_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator");
--- /dev/null
+/*
+ * Copyright (c) 2013 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
+
+static u8 clk_composite_get_parent(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mux_ops = composite->mux_ops;
+ struct clk_hw *mux_hw = composite->mux_hw;
+
+ mux_hw->clk = hw->clk;
+
+ return mux_ops->get_parent(mux_hw);
+}
+
+static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mux_ops = composite->mux_ops;
+ struct clk_hw *mux_hw = composite->mux_hw;
+
+ mux_hw->clk = hw->clk;
+
+ return mux_ops->set_parent(mux_hw, index);
+}
+
+static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *div_ops = composite->div_ops;
+ struct clk_hw *div_hw = composite->div_hw;
+
+ div_hw->clk = hw->clk;
+
+ return div_ops->recalc_rate(div_hw, parent_rate);
+}
+
+static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *div_ops = composite->div_ops;
+ struct clk_hw *div_hw = composite->div_hw;
+
+ div_hw->clk = hw->clk;
+
+ return div_ops->round_rate(div_hw, rate, prate);
+}
+
+static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *div_ops = composite->div_ops;
+ struct clk_hw *div_hw = composite->div_hw;
+
+ div_hw->clk = hw->clk;
+
+ return div_ops->set_rate(div_hw, rate, parent_rate);
+}
+
+static int clk_composite_is_enabled(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ return gate_ops->is_enabled(gate_hw);
+}
+
+static int clk_composite_enable(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ return gate_ops->enable(gate_hw);
+}
+
+static void clk_composite_disable(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ gate_ops->disable(gate_hw);
+}
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+ const char **parent_names, int num_parents,
+ struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+ struct clk_hw *div_hw, const struct clk_ops *div_ops,
+ struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+ unsigned long flags)
+{
+ struct clk *clk;
+ struct clk_init_data init;
+ struct clk_composite *composite;
+ struct clk_ops *clk_composite_ops;
+
+ composite = kzalloc(sizeof(*composite), GFP_KERNEL);
+ if (!composite) {
+ pr_err("%s: could not allocate composite clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.flags = flags | CLK_IS_BASIC;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ clk_composite_ops = &composite->ops;
+
+ if (mux_hw && mux_ops) {
+ if (!mux_ops->get_parent || !mux_ops->set_parent) {
+ clk = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ composite->mux_hw = mux_hw;
+ composite->mux_ops = mux_ops;
+ clk_composite_ops->get_parent = clk_composite_get_parent;
+ clk_composite_ops->set_parent = clk_composite_set_parent;
+ }
+
+ if (div_hw && div_ops) {
+ if (!div_ops->recalc_rate || !div_ops->round_rate ||
+ !div_ops->set_rate) {
+ clk = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ composite->div_hw = div_hw;
+ composite->div_ops = div_ops;
+ clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
+ clk_composite_ops->round_rate = clk_composite_round_rate;
+ clk_composite_ops->set_rate = clk_composite_set_rate;
+ }
+
+ if (gate_hw && gate_ops) {
+ if (!gate_ops->is_enabled || !gate_ops->enable ||
+ !gate_ops->disable) {
+ clk = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ composite->gate_hw = gate_hw;
+ composite->gate_ops = gate_ops;
+ clk_composite_ops->is_enabled = clk_composite_is_enabled;
+ clk_composite_ops->enable = clk_composite_enable;
+ clk_composite_ops->disable = clk_composite_disable;
+ }
+
+ init.ops = clk_composite_ops;
+ composite->hw.init = &init;
+
+ clk = clk_register(dev, &composite->hw);
+ if (IS_ERR(clk))
+ goto err;
+
+ if (composite->mux_hw)
+ composite->mux_hw->clk = clk;
+
+ if (composite->div_hw)
+ composite->div_hw->clk = clk;
+
+ if (composite->gate_hw)
+ composite->gate_hw->clk = clk;
+
+ return clk;
+
+err:
+ kfree(composite);
+ return clk;
+}
static u8 clk_mux_get_parent(struct clk_hw *hw)
{
struct clk_mux *mux = to_clk_mux(hw);
+ int num_parents = __clk_get_num_parents(hw->clk);
u32 val;
/*
* val = 0x4 really means "bit 2, index starts at bit 0"
*/
val = readl(mux->reg) >> mux->shift;
- val &= (1 << mux->width) - 1;
+ val &= mux->mask;
+
+ if (mux->table) {
+ int i;
+
+ for (i = 0; i < num_parents; i++)
+ if (mux->table[i] == val)
+ return i;
+ return -EINVAL;
+ }
if (val && (mux->flags & CLK_MUX_INDEX_BIT))
val = ffs(val) - 1;
if (val && (mux->flags & CLK_MUX_INDEX_ONE))
val--;
- if (val >= __clk_get_num_parents(hw->clk))
+ if (val >= num_parents)
return -EINVAL;
return val;
u32 val;
unsigned long flags = 0;
- if (mux->flags & CLK_MUX_INDEX_BIT)
- index = (1 << ffs(index));
+ if (mux->table)
+ index = mux->table[index];
- if (mux->flags & CLK_MUX_INDEX_ONE)
- index++;
+ else {
+ if (mux->flags & CLK_MUX_INDEX_BIT)
+ index = (1 << ffs(index));
+
+ if (mux->flags & CLK_MUX_INDEX_ONE)
+ index++;
+ }
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
val = readl(mux->reg);
- val &= ~(((1 << mux->width) - 1) << mux->shift);
+ val &= ~(mux->mask << mux->shift);
val |= index << mux->shift;
writel(val, mux->reg);
};
EXPORT_SYMBOL_GPL(clk_mux_ops);
-struct clk *clk_register_mux(struct device *dev, const char *name,
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
const char **parent_names, u8 num_parents, unsigned long flags,
- void __iomem *reg, u8 shift, u8 width,
- u8 clk_mux_flags, spinlock_t *lock)
+ void __iomem *reg, u8 shift, u32 mask,
+ u8 clk_mux_flags, u32 *table, spinlock_t *lock)
{
struct clk_mux *mux;
struct clk *clk;
/* struct clk_mux assignments */
mux->reg = reg;
mux->shift = shift;
- mux->width = width;
+ mux->mask = mask;
mux->flags = clk_mux_flags;
mux->lock = lock;
+ mux->table = table;
mux->hw.init = &init;
clk = clk_register(dev, &mux->hw);
return clk;
}
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u8 width,
+ u8 clk_mux_flags, spinlock_t *lock)
+{
+ u32 mask = BIT(width) - 1;
+
+ return clk_register_mux_table(dev, name, parent_names, num_parents,
+ flags, reg, shift, mask, clk_mux_flags,
+ NULL, lock);
+}
for (i = pll1; i < maxclk; i++) {
prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
- BUG_ON(!prima2_clks[i]);
+ BUG_ON(IS_ERR(prima2_clks[i]));
}
clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
clk_register_clkdev(prima2_clks[io], NULL, "io");
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/clk-provider.h>
+#include <linux/clk/zynq.h>
static void __iomem *slcr_base;
#include <linux/of.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/sched.h>
static DEFINE_SPINLOCK(enable_lock);
static DEFINE_MUTEX(prepare_lock);
+static struct task_struct *prepare_owner;
+static struct task_struct *enable_owner;
+
+static int prepare_refcnt;
+static int enable_refcnt;
+
static HLIST_HEAD(clk_root_list);
static HLIST_HEAD(clk_orphan_list);
static LIST_HEAD(clk_notifier_list);
+/*** locking ***/
+static void clk_prepare_lock(void)
+{
+ if (!mutex_trylock(&prepare_lock)) {
+ if (prepare_owner == current) {
+ prepare_refcnt++;
+ return;
+ }
+ mutex_lock(&prepare_lock);
+ }
+ WARN_ON_ONCE(prepare_owner != NULL);
+ WARN_ON_ONCE(prepare_refcnt != 0);
+ prepare_owner = current;
+ prepare_refcnt = 1;
+}
+
+static void clk_prepare_unlock(void)
+{
+ WARN_ON_ONCE(prepare_owner != current);
+ WARN_ON_ONCE(prepare_refcnt == 0);
+
+ if (--prepare_refcnt)
+ return;
+ prepare_owner = NULL;
+ mutex_unlock(&prepare_lock);
+}
+
+static unsigned long clk_enable_lock(void)
+{
+ unsigned long flags;
+
+ if (!spin_trylock_irqsave(&enable_lock, flags)) {
+ if (enable_owner == current) {
+ enable_refcnt++;
+ return flags;
+ }
+ spin_lock_irqsave(&enable_lock, flags);
+ }
+ WARN_ON_ONCE(enable_owner != NULL);
+ WARN_ON_ONCE(enable_refcnt != 0);
+ enable_owner = current;
+ enable_refcnt = 1;
+ return flags;
+}
+
+static void clk_enable_unlock(unsigned long flags)
+{
+ WARN_ON_ONCE(enable_owner != current);
+ WARN_ON_ONCE(enable_refcnt == 0);
+
+ if (--enable_refcnt)
+ return;
+ enable_owner = NULL;
+ spin_unlock_irqrestore(&enable_lock, flags);
+}
+
/*** debugfs support ***/
#ifdef CONFIG_COMMON_CLK_DEBUG
seq_printf(s, " clock enable_cnt prepare_cnt rate\n");
seq_printf(s, "---------------------------------------------------------------------\n");
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(c, &clk_root_list, child_node)
clk_summary_show_subtree(s, c, 0);
hlist_for_each_entry(c, &clk_orphan_list, child_node)
clk_summary_show_subtree(s, c, 0);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return 0;
}
seq_printf(s, "{");
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(c, &clk_root_list, child_node) {
if (!first_node)
clk_dump_subtree(s, c, 0);
}
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
seq_printf(s, "}");
return 0;
if (!orphandir)
return -ENOMEM;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(clk, &clk_root_list, child_node)
clk_debug_create_subtree(clk, rootdir);
inited = 1;
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return 0;
}
static inline int clk_debug_register(struct clk *clk) { return 0; }
#endif
+/* caller must hold prepare_lock */
+static void clk_unprepare_unused_subtree(struct clk *clk)
+{
+ struct clk *child;
+
+ if (!clk)
+ return;
+
+ hlist_for_each_entry(child, &clk->children, child_node)
+ clk_unprepare_unused_subtree(child);
+
+ if (clk->prepare_count)
+ return;
+
+ if (clk->flags & CLK_IGNORE_UNUSED)
+ return;
+
+ if (__clk_is_prepared(clk)) {
+ if (clk->ops->unprepare_unused)
+ clk->ops->unprepare_unused(clk->hw);
+ else if (clk->ops->unprepare)
+ clk->ops->unprepare(clk->hw);
+ }
+}
+
/* caller must hold prepare_lock */
static void clk_disable_unused_subtree(struct clk *clk)
{
hlist_for_each_entry(child, &clk->children, child_node)
clk_disable_unused_subtree(child);
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
if (clk->enable_count)
goto unlock_out;
}
unlock_out:
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
out:
return;
{
struct clk *clk;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(clk, &clk_root_list, child_node)
clk_disable_unused_subtree(clk);
hlist_for_each_entry(clk, &clk_orphan_list, child_node)
clk_disable_unused_subtree(clk);
- mutex_unlock(&prepare_lock);
+ hlist_for_each_entry(clk, &clk_root_list, child_node)
+ clk_unprepare_unused_subtree(clk);
+
+ hlist_for_each_entry(clk, &clk_orphan_list, child_node)
+ clk_unprepare_unused_subtree(clk);
+
+ clk_prepare_unlock();
return 0;
}
return !clk ? 0 : clk->flags;
}
+bool __clk_is_prepared(struct clk *clk)
+{
+ int ret;
+
+ if (!clk)
+ return false;
+
+ /*
+ * .is_prepared is optional for clocks that can prepare
+ * fall back to software usage counter if it is missing
+ */
+ if (!clk->ops->is_prepared) {
+ ret = clk->prepare_count ? 1 : 0;
+ goto out;
+ }
+
+ ret = clk->ops->is_prepared(clk->hw);
+out:
+ return !!ret;
+}
+
bool __clk_is_enabled(struct clk *clk)
{
int ret;
*/
void clk_unprepare(struct clk *clk)
{
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
__clk_unprepare(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
}
EXPORT_SYMBOL_GPL(clk_unprepare);
{
int ret;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
ret = __clk_prepare(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
{
unsigned long flags;
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
__clk_disable(clk);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
}
EXPORT_SYMBOL_GPL(clk_disable);
unsigned long flags;
int ret;
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
ret = __clk_enable(clk);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
return ret;
}
{
unsigned long ret;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
ret = __clk_round_rate(clk, rate);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
{
unsigned long rate;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
__clk_recalc_rates(clk, 0);
rate = __clk_get_rate(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return rate;
}
int ret = NOTIFY_DONE;
if (clk->rate == clk->new_rate)
- return 0;
+ return NULL;
if (clk->notifier_count) {
ret = __clk_notify(clk, event, clk->rate, clk->new_rate);
int ret = 0;
/* prevent racing with updates to the clock topology */
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
/* bail early if nothing to do */
if (rate == clk->rate)
clk_change_rate(top);
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
{
struct clk *parent;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
parent = __clk_get_parent(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return parent;
}
__clk_prepare(parent);
/* FIXME replace with clk_is_enabled(clk) someday */
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
if (clk->enable_count)
__clk_enable(parent);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
/* change clock input source */
ret = clk->ops->set_parent(clk->hw, i);
/* clean up old prepare and enable */
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
if (clk->enable_count)
__clk_disable(old_parent);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
if (clk->prepare_count)
__clk_unprepare(old_parent);
return -ENOSYS;
/* prevent racing with updates to the clock topology */
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
if (clk->parent == parent)
goto out;
__clk_reparent(clk, parent);
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
if (!clk)
return -EINVAL;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
/* check to see if a clock with this name is already registered */
if (__clk_lookup(clk->name)) {
clk_debug_register(clk);
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
if (!clk || !nb)
return -EINVAL;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
/* search the list of notifiers for this clk */
list_for_each_entry(cn, &clk_notifier_list, node)
clk->notifier_count++;
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
if (!clk || !nb)
return -EINVAL;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
list_for_each_entry(cn, &clk_notifier_list, node)
if (cn->clk == clk)
ret = -ENOENT;
}
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
-#include <mach/common.h>
-#include <mach/mx23.h>
+#include <linux/of_address.h>
#include "clk.h"
-#define DIGCTRL MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
-#define CLKCTRL MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+static void __iomem *clkctrl;
+static void __iomem *digctrl;
+
+#define CLKCTRL clkctrl
+#define DIGCTRL digctrl
+
#define PLLCTRL0 (CLKCTRL + 0x0000)
#define CPU (CLKCTRL + 0x0020)
#define HBUS (CLKCTRL + 0x0030)
u32 val;
/* Gate off cpu clock in WFI for power saving */
- __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
+ writel_relaxed(1 << BP_CPU_INTERRUPT_WAIT, CPU + SET);
/* Clear BYPASS for SAIF */
- __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ);
+ writel_relaxed(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ + CLR);
/* SAIF has to use frac div for functional operation */
val = readl_relaxed(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);
+ writel_relaxed(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ + CLR);
/*
* 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);
+ writel_relaxed(0x3f << BP_FRAC_IOFRAC, FRAC + CLR);
+ writel_relaxed(30 << BP_FRAC_IOFRAC, FRAC + SET);
}
static const char *sel_pll[] __initconst = { "pll", "ref_xtal", };
struct device_node *np;
u32 i;
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
+ digctrl = of_iomap(np, 0);
+ WARN_ON(!digctrl);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx23-clkctrl");
+ clkctrl = of_iomap(np, 0);
+ WARN_ON(!clkctrl);
+
clk_misc_init();
clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
return PTR_ERR(clks[i]);
}
- np = of_find_compatible_node(NULL, NULL, "fsl,imx23-clkctrl");
- if (np) {
- clk_data.clks = clks;
- clk_data.clk_num = ARRAY_SIZE(clks);
- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- }
-
- clk_register_clkdev(clks[clk32k], NULL, "timrot");
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_prepare_enable(clks[clks_init_on[i]]);
- mxs_timer_init();
-
return 0;
}
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
-#include <mach/common.h>
-#include <mach/mx28.h>
+#include <linux/of_address.h>
#include "clk.h"
-#define CLKCTRL MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+static void __iomem *clkctrl;
+#define CLKCTRL clkctrl
+
#define PLL0CTRL0 (CLKCTRL + 0x0000)
#define PLL1CTRL0 (CLKCTRL + 0x0020)
#define PLL2CTRL0 (CLKCTRL + 0x0040)
#define BP_FRAC0_IO1FRAC 16
#define BP_FRAC0_IO0FRAC 24
-#define DIGCTRL MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+static void __iomem *digctrl;
+#define DIGCTRL digctrl
#define BP_SAIF_CLKMUX 10
/*
if (clkmux > 0x3)
return -EINVAL;
- __mxs_clrl(0x3 << BP_SAIF_CLKMUX, DIGCTRL);
- __mxs_setl(clkmux << BP_SAIF_CLKMUX, DIGCTRL);
+ writel_relaxed(0x3 << BP_SAIF_CLKMUX, DIGCTRL + CLR);
+ writel_relaxed(clkmux << BP_SAIF_CLKMUX, DIGCTRL + SET);
return 0;
}
u32 val;
/* Gate off cpu clock in WFI for power saving */
- __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
+ writel_relaxed(1 << BP_CPU_INTERRUPT_WAIT, CPU + SET);
/* 0 is a bad default value for a divider */
- __mxs_setl(1 << BP_ENET_DIV_TIME, ENET);
+ writel_relaxed(1 << BP_ENET_DIV_TIME, ENET + SET);
/* Clear BYPASS for SAIF */
- __mxs_clrl(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ);
+ writel_relaxed(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ + CLR);
/* SAIF has to use frac div for functional operation */
val = readl_relaxed(SAIF0);
* 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);
+ writel_relaxed(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ + CLR);
/*
* 480 MHz seems too high to be ssp clock source directly,
struct device_node *np;
u32 i;
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx28-digctl");
+ digctrl = of_iomap(np, 0);
+ WARN_ON(!digctrl);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx28-clkctrl");
+ clkctrl = of_iomap(np, 0);
+ WARN_ON(!clkctrl);
+
clk_misc_init();
clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
return PTR_ERR(clks[i]);
}
- np = of_find_compatible_node(NULL, NULL, "fsl,imx28-clkctrl");
- if (np) {
- clk_data.clks = clks;
- clk_data.clk_num = ARRAY_SIZE(clks);
- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- }
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- clk_register_clkdev(clks[xbus], NULL, "timrot");
clk_register_clkdev(clks[enet_out], NULL, "enet_out");
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_prepare_enable(clks[clks_init_on[i]]);
- mxs_timer_init();
-
return 0;
}
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
+#include "clk.h"
DEFINE_SPINLOCK(mxs_lock);
SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "d0100000.spdif-in");
- clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0,
+ clk = clk_register_gate(NULL, "acp_clk", "ahb_clk", 0,
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "acp_clk");
- clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0,
+ clk = clk_register_gate(NULL, "plgpio_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "e2800000.gpio");
- clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0,
+ clk = clk_register_gate(NULL, "video_dec_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "video_dec");
- clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mclk", 0,
+ clk = clk_register_gate(NULL, "video_enc_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "video_enc");
- clk = clk_register_gate(NULL, "video_in_clk", "video_in_mclk", 0,
+ clk = clk_register_gate(NULL, "video_in_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "spear_vip");
- clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0,
+ clk = clk_register_gate(NULL, "cam0_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0200000.cam0");
- clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0,
+ clk = clk_register_gate(NULL, "cam1_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0300000.cam1");
- clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0,
+ clk = clk_register_gate(NULL, "cam2_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0400000.cam2");
- clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0,
+ clk = clk_register_gate(NULL, "cam3_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0500000.cam3");
--- /dev/null
+#
+# Makefile for sunxi specific clk
+#
+
+obj-y += clk-sunxi.o clk-factors.o
--- /dev/null
+/*
+ * Copyright (C) 2013 Emilio López <emilio@elopez.com.ar>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Adjustable factor-based clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+#include <linux/delay.h>
+
+#include "clk-factors.h"
+
+/*
+ * DOC: basic adjustable factor-based clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.
+ * clk->rate = (parent->rate * N * (K + 1) >> P) / (M + 1)
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+struct clk_factors {
+ struct clk_hw hw;
+ void __iomem *reg;
+ struct clk_factors_config *config;
+ void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
+ spinlock_t *lock;
+};
+
+#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+
+#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos))
+#define CLRMASK(len, pos) (~(SETMASK(len, pos)))
+#define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit))
+
+#define FACTOR_SET(bit, len, reg, val) \
+ (((reg) & CLRMASK(len, bit)) | (val << (bit)))
+
+static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u8 n = 1, k = 0, p = 0, m = 0;
+ u32 reg;
+ unsigned long rate;
+ struct clk_factors *factors = to_clk_factors(hw);
+ struct clk_factors_config *config = factors->config;
+
+ /* Fetch the register value */
+ reg = readl(factors->reg);
+
+ /* Get each individual factor if applicable */
+ if (config->nwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ n = FACTOR_GET(config->nshift, config->nwidth, reg);
+ if (config->kwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ k = FACTOR_GET(config->kshift, config->kwidth, reg);
+ if (config->mwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ m = FACTOR_GET(config->mshift, config->mwidth, reg);
+ if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ p = FACTOR_GET(config->pshift, config->pwidth, reg);
+
+ /* Calculate the rate */
+ rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+
+ return rate;
+}
+
+static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct clk_factors *factors = to_clk_factors(hw);
+ factors->get_factors((u32 *)&rate, (u32)*parent_rate,
+ NULL, NULL, NULL, NULL);
+
+ return rate;
+}
+
+static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u8 n, k, m, p;
+ u32 reg;
+ struct clk_factors *factors = to_clk_factors(hw);
+ struct clk_factors_config *config = factors->config;
+ unsigned long flags = 0;
+
+ factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p);
+
+ if (factors->lock)
+ spin_lock_irqsave(factors->lock, flags);
+
+ /* Fetch the register value */
+ reg = readl(factors->reg);
+
+ /* Set up the new factors - macros do not do anything if width is 0 */
+ reg = FACTOR_SET(config->nshift, config->nwidth, reg, n);
+ reg = FACTOR_SET(config->kshift, config->kwidth, reg, k);
+ reg = FACTOR_SET(config->mshift, config->mwidth, reg, m);
+ reg = FACTOR_SET(config->pshift, config->pwidth, reg, p);
+
+ /* Apply them now */
+ writel(reg, factors->reg);
+
+ /* delay 500us so pll stabilizes */
+ __delay((rate >> 20) * 500 / 2);
+
+ if (factors->lock)
+ spin_unlock_irqrestore(factors->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops clk_factors_ops = {
+ .recalc_rate = clk_factors_recalc_rate,
+ .round_rate = clk_factors_round_rate,
+ .set_rate = clk_factors_set_rate,
+};
+
+/**
+ * clk_register_factors - register a factors clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust factors
+ * @config: shift and width of factors n, k, m and p
+ * @get_factors: function to calculate the factors for a given frequency
+ * @lock: shared register lock for this clock
+ */
+struct clk *clk_register_factors(struct device *dev, const char *name,
+ const char *parent_name,
+ unsigned long flags, void __iomem *reg,
+ struct clk_factors_config *config,
+ void (*get_factors)(u32 *rate, u32 parent,
+ u8 *n, u8 *k, u8 *m, u8 *p),
+ spinlock_t *lock)
+{
+ struct clk_factors *factors;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ /* allocate the factors */
+ factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+ if (!factors) {
+ pr_err("%s: could not allocate factors clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.ops = &clk_factors_ops;
+ init.flags = flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ /* struct clk_factors assignments */
+ factors->reg = reg;
+ factors->config = config;
+ factors->lock = lock;
+ factors->hw.init = &init;
+ factors->get_factors = get_factors;
+
+ /* register the clock */
+ clk = clk_register(dev, &factors->hw);
+
+ if (IS_ERR(clk))
+ kfree(factors);
+
+ return clk;
+}
--- /dev/null
+#ifndef __MACH_SUNXI_CLK_FACTORS_H
+#define __MACH_SUNXI_CLK_FACTORS_H
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+#define SUNXI_FACTORS_NOT_APPLICABLE (0)
+
+struct clk_factors_config {
+ u8 nshift;
+ u8 nwidth;
+ u8 kshift;
+ u8 kwidth;
+ u8 mshift;
+ u8 mwidth;
+ u8 pshift;
+ u8 pwidth;
+};
+
+struct clk *clk_register_factors(struct device *dev, const char *name,
+ const char *parent_name,
+ unsigned long flags, void __iomem *reg,
+ struct clk_factors_config *config,
+ void (*get_factors) (u32 *rate, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p),
+ spinlock_t *lock);
+#endif
--- /dev/null
+/*
+ * Copyright 2013 Emilio López
+ *
+ * Emilio López <emilio@elopez.com.ar>
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/sunxi.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk-factors.h"
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/**
+ * sunxi_osc_clk_setup() - Setup function for gatable oscillator
+ */
+
+#define SUNXI_OSC24M_GATE 0
+
+static void __init sunxi_osc_clk_setup(struct device_node *node)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *parent;
+ void *reg;
+
+ reg = of_iomap(node, 0);
+
+ parent = of_clk_get_parent_name(node, 0);
+
+ clk = clk_register_gate(NULL, clk_name, parent, CLK_IGNORE_UNUSED,
+ reg, SUNXI_OSC24M_GATE, 0, &clk_lock);
+
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1
+ * PLL1 rate is calculated as follows
+ * rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+ * parent_rate is always 24Mhz
+ */
+
+static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 div;
+
+ /* Normalize value to a 6M multiple */
+ div = *freq / 6000000;
+ *freq = 6000000 * div;
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ /* m is always zero for pll1 */
+ *m = 0;
+
+ /* k is 1 only on these cases */
+ if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000)
+ *k = 1;
+ else
+ *k = 0;
+
+ /* p will be 3 for divs under 10 */
+ if (div < 10)
+ *p = 3;
+
+ /* p will be 2 for divs between 10 - 20 and odd divs under 32 */
+ else if (div < 20 || (div < 32 && (div & 1)))
+ *p = 2;
+
+ /* p will be 1 for even divs under 32, divs under 40 and odd pairs
+ * of divs between 40-62 */
+ else if (div < 40 || (div < 64 && (div & 2)))
+ *p = 1;
+
+ /* any other entries have p = 0 */
+ else
+ *p = 0;
+
+ /* calculate a suitable n based on k and p */
+ div <<= *p;
+ div /= (*k + 1);
+ *n = div / 4;
+}
+
+
+
+/**
+ * sunxi_get_apb1_factors() - calculates m, p factors for APB1
+ * APB1 rate is calculated as follows
+ * rate = (parent_rate >> p) / (m + 1);
+ */
+
+static void sunxi_get_apb1_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 calcm, calcp;
+
+ if (parent_rate < *freq)
+ *freq = parent_rate;
+
+ parent_rate = (parent_rate + (*freq - 1)) / *freq;
+
+ /* Invalid rate! */
+ if (parent_rate > 32)
+ return;
+
+ if (parent_rate <= 4)
+ calcp = 0;
+ else if (parent_rate <= 8)
+ calcp = 1;
+ else if (parent_rate <= 16)
+ calcp = 2;
+ else
+ calcp = 3;
+
+ calcm = (parent_rate >> calcp) - 1;
+
+ *freq = (parent_rate >> calcp) / (calcm + 1);
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ *m = calcm;
+ *p = calcp;
+}
+
+
+
+/**
+ * sunxi_factors_clk_setup() - Setup function for factor clocks
+ */
+
+struct factors_data {
+ struct clk_factors_config *table;
+ void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
+};
+
+static struct clk_factors_config pll1_config = {
+ .nshift = 8,
+ .nwidth = 5,
+ .kshift = 4,
+ .kwidth = 2,
+ .mshift = 0,
+ .mwidth = 2,
+ .pshift = 16,
+ .pwidth = 2,
+};
+
+static struct clk_factors_config apb1_config = {
+ .mshift = 0,
+ .mwidth = 5,
+ .pshift = 16,
+ .pwidth = 2,
+};
+
+static const __initconst struct factors_data pll1_data = {
+ .table = &pll1_config,
+ .getter = sunxi_get_pll1_factors,
+};
+
+static const __initconst struct factors_data apb1_data = {
+ .table = &apb1_config,
+ .getter = sunxi_get_apb1_factors,
+};
+
+static void __init sunxi_factors_clk_setup(struct device_node *node,
+ struct factors_data *data)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *parent;
+ void *reg;
+
+ reg = of_iomap(node, 0);
+
+ parent = of_clk_get_parent_name(node, 0);
+
+ clk = clk_register_factors(NULL, clk_name, parent, CLK_IGNORE_UNUSED,
+ reg, data->table, data->getter, &clk_lock);
+
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_mux_clk_setup() - Setup function for muxes
+ */
+
+#define SUNXI_MUX_GATE_WIDTH 2
+
+struct mux_data {
+ u8 shift;
+};
+
+static const __initconst struct mux_data cpu_data = {
+ .shift = 16,
+};
+
+static const __initconst struct mux_data apb1_mux_data = {
+ .shift = 24,
+};
+
+static void __init sunxi_mux_clk_setup(struct device_node *node,
+ struct mux_data *data)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char **parents = kmalloc(sizeof(char *) * 5, GFP_KERNEL);
+ void *reg;
+ int i = 0;
+
+ reg = of_iomap(node, 0);
+
+ while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+ i++;
+
+ clk = clk_register_mux(NULL, clk_name, parents, i, 0, reg,
+ data->shift, SUNXI_MUX_GATE_WIDTH,
+ 0, &clk_lock);
+
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_divider_clk_setup() - Setup function for simple divider clocks
+ */
+
+#define SUNXI_DIVISOR_WIDTH 2
+
+struct div_data {
+ u8 shift;
+ u8 pow;
+};
+
+static const __initconst struct div_data axi_data = {
+ .shift = 0,
+ .pow = 0,
+};
+
+static const __initconst struct div_data ahb_data = {
+ .shift = 4,
+ .pow = 1,
+};
+
+static const __initconst struct div_data apb0_data = {
+ .shift = 8,
+ .pow = 1,
+};
+
+static void __init sunxi_divider_clk_setup(struct device_node *node,
+ struct div_data *data)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *clk_parent;
+ void *reg;
+
+ reg = of_iomap(node, 0);
+
+ clk_parent = of_clk_get_parent_name(node, 0);
+
+ clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
+ reg, data->shift, SUNXI_DIVISOR_WIDTH,
+ data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
+ &clk_lock);
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+/* Matches for of_clk_init */
+static const __initconst struct of_device_id clk_match[] = {
+ {.compatible = "fixed-clock", .data = of_fixed_clk_setup,},
+ {.compatible = "allwinner,sun4i-osc-clk", .data = sunxi_osc_clk_setup,},
+ {}
+};
+
+/* Matches for factors clocks */
+static const __initconst struct of_device_id clk_factors_match[] = {
+ {.compatible = "allwinner,sun4i-pll1-clk", .data = &pll1_data,},
+ {.compatible = "allwinner,sun4i-apb1-clk", .data = &apb1_data,},
+ {}
+};
+
+/* Matches for divider clocks */
+static const __initconst struct of_device_id clk_div_match[] = {
+ {.compatible = "allwinner,sun4i-axi-clk", .data = &axi_data,},
+ {.compatible = "allwinner,sun4i-ahb-clk", .data = &ahb_data,},
+ {.compatible = "allwinner,sun4i-apb0-clk", .data = &apb0_data,},
+ {}
+};
+
+/* Matches for mux clocks */
+static const __initconst struct of_device_id clk_mux_match[] = {
+ {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_data,},
+ {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,},
+ {}
+};
+
+static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match,
+ void *function)
+{
+ struct device_node *np;
+ const struct div_data *data;
+ const struct of_device_id *match;
+ void (*setup_function)(struct device_node *, const void *) = function;
+
+ for_each_matching_node(np, clk_match) {
+ match = of_match_node(clk_match, np);
+ data = match->data;
+ setup_function(np, data);
+ }
+}
+
+void __init sunxi_init_clocks(void)
+{
+ /* Register all the simple sunxi clocks on DT */
+ of_clk_init(clk_match);
+
+ /* Register factor clocks */
+ of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
+
+ /* Register divider clocks */
+ of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
+
+ /* Register mux clocks */
+ of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
+}
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
#define write_rst_clr(val, gate) \
writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
-#define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32))
+#define periph_clk_to_bit(gate) (1 << (gate->clk_num % 32))
+
+#define LVL2_CLK_GATE_OVRE 0x554
/* Peripheral gate clock ops */
static int clk_periph_is_enabled(struct clk_hw *hw)
}
}
+ if (gate->flags & TEGRA_PERIPH_WAR_1005168) {
+ writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE);
+ writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE);
+ udelay(1);
+ writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE);
+ }
+
spin_unlock_irqrestore(&periph_ref_lock, flags);
return 0;
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/export.h>
#include <linux/slab.h>
#include <linux/err.h>
tegra_periph_reset(gate, 0);
}
+EXPORT_SYMBOL(tegra_periph_reset_deassert);
void tegra_periph_reset_assert(struct clk *c)
{
tegra_periph_reset(gate, 1);
}
+EXPORT_SYMBOL(tegra_periph_reset_assert);
const struct clk_ops tegra_clk_periph_ops = {
.get_parent = clk_periph_get_parent,
static struct clk *_tegra_clk_register_periph(const char *name,
const char **parent_names, int num_parents,
struct tegra_clk_periph *periph,
- void __iomem *clk_base, u32 offset, bool div)
+ void __iomem *clk_base, u32 offset, bool div,
+ unsigned long flags)
{
struct clk *clk;
struct clk_init_data init;
init.name = name;
init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops;
- init.flags = div ? 0 : CLK_SET_RATE_PARENT;
+ init.flags = flags;
init.parent_names = parent_names;
init.num_parents = num_parents;
struct clk *tegra_clk_register_periph(const char *name,
const char **parent_names, int num_parents,
struct tegra_clk_periph *periph, void __iomem *clk_base,
- u32 offset)
+ u32 offset, unsigned long flags)
{
return _tegra_clk_register_periph(name, parent_names, num_parents,
- periph, clk_base, offset, true);
+ periph, clk_base, offset, true, flags);
}
struct clk *tegra_clk_register_periph_nodiv(const char *name,
u32 offset)
{
return _tegra_clk_register_periph(name, parent_names, num_parents,
- periph, clk_base, offset, false);
+ periph, clk_base, offset, false, CLK_SET_RATE_PARENT);
}
/*
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
#define PLLE_SS_CTRL 0x68
#define PLLE_SS_DISABLE (7 << 10)
+#define PLLE_AUX_PLLP_SEL BIT(2)
+#define PLLE_AUX_ENABLE_SWCTL BIT(4)
+#define PLLE_AUX_SEQ_ENABLE BIT(24)
+#define PLLE_AUX_PLLRE_SEL BIT(28)
+
+#define PLLE_MISC_PLLE_PTS BIT(8)
+#define PLLE_MISC_IDDQ_SW_VALUE BIT(13)
+#define PLLE_MISC_IDDQ_SW_CTRL BIT(14)
+#define PLLE_MISC_VREG_BG_CTRL_SHIFT 4
+#define PLLE_MISC_VREG_BG_CTRL_MASK (3 << PLLE_MISC_VREG_BG_CTRL_SHIFT)
+#define PLLE_MISC_VREG_CTRL_SHIFT 2
+#define PLLE_MISC_VREG_CTRL_MASK (2 << PLLE_MISC_VREG_CTRL_SHIFT)
+
+#define PLLCX_MISC_STROBE BIT(31)
+#define PLLCX_MISC_RESET BIT(30)
+#define PLLCX_MISC_SDM_DIV_SHIFT 28
+#define PLLCX_MISC_SDM_DIV_MASK (0x3 << PLLCX_MISC_SDM_DIV_SHIFT)
+#define PLLCX_MISC_FILT_DIV_SHIFT 26
+#define PLLCX_MISC_FILT_DIV_MASK (0x3 << PLLCX_MISC_FILT_DIV_SHIFT)
+#define PLLCX_MISC_ALPHA_SHIFT 18
+#define PLLCX_MISC_DIV_LOW_RANGE \
+ ((0x1 << PLLCX_MISC_SDM_DIV_SHIFT) | \
+ (0x1 << PLLCX_MISC_FILT_DIV_SHIFT))
+#define PLLCX_MISC_DIV_HIGH_RANGE \
+ ((0x2 << PLLCX_MISC_SDM_DIV_SHIFT) | \
+ (0x2 << PLLCX_MISC_FILT_DIV_SHIFT))
+#define PLLCX_MISC_COEF_LOW_RANGE \
+ ((0x14 << PLLCX_MISC_KA_SHIFT) | (0x38 << PLLCX_MISC_KB_SHIFT))
+#define PLLCX_MISC_KA_SHIFT 2
+#define PLLCX_MISC_KB_SHIFT 9
+#define PLLCX_MISC_DEFAULT (PLLCX_MISC_COEF_LOW_RANGE | \
+ (0x19 << PLLCX_MISC_ALPHA_SHIFT) | \
+ PLLCX_MISC_DIV_LOW_RANGE | \
+ PLLCX_MISC_RESET)
+#define PLLCX_MISC1_DEFAULT 0x000d2308
+#define PLLCX_MISC2_DEFAULT 0x30211200
+#define PLLCX_MISC3_DEFAULT 0x200
+
+#define PMC_PLLM_WB0_OVERRIDE 0x1dc
+#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
+#define PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK BIT(27)
+
#define PMC_SATA_PWRGT 0x1ac
#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
#define divn_max(p) (divn_mask(p))
#define divp_max(p) (1 << (divp_mask(p)))
+
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+/* PLLXC has 4-bit PDIV, but entry 15 is not allowed in h/w */
+#define PLLXC_PDIV_MAX 14
+
+/* non-monotonic mapping below is not a typo */
+static u8 pllxc_p[PLLXC_PDIV_MAX + 1] = {
+ /* PDIV: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 */
+ /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32
+};
+
+#define PLLCX_PDIV_MAX 7
+static u8 pllcx_p[PLLCX_PDIV_MAX + 1] = {
+ /* PDIV: 0, 1, 2, 3, 4, 5, 6, 7 */
+ /* p: */ 1, 2, 3, 4, 6, 8, 12, 16
+};
+#endif
+
static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
{
u32 val;
if (!(pll->flags & TEGRA_PLL_USE_LOCK))
return;
+ if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE))
+ return;
+
val = pll_readl_misc(pll);
val |= BIT(pll->params->lock_enable_bit_idx);
pll_writel_misc(val, pll);
}
-static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll,
- void __iomem *lock_addr, u32 lock_bit_idx)
+static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll)
{
int i;
- u32 val;
+ u32 val, lock_mask;
+ void __iomem *lock_addr;
if (!(pll->flags & TEGRA_PLL_USE_LOCK)) {
udelay(pll->params->lock_delay);
return 0;
}
+ lock_addr = pll->clk_base;
+ if (pll->flags & TEGRA_PLL_LOCK_MISC)
+ lock_addr += pll->params->misc_reg;
+ else
+ lock_addr += pll->params->base_reg;
+
+ lock_mask = pll->params->lock_mask;
+
for (i = 0; i < pll->params->lock_delay; i++) {
val = readl_relaxed(lock_addr);
- if (val & BIT(lock_bit_idx)) {
+ if ((val & lock_mask) == lock_mask) {
udelay(PLL_POST_LOCK_DELAY);
return 0;
}
return val & PLL_BASE_ENABLE ? 1 : 0;
}
-static int _clk_pll_enable(struct clk_hw *hw)
+static void _clk_pll_enable(struct clk_hw *hw)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
u32 val;
clk_pll_enable_lock(pll);
val = pll_readl_base(pll);
- val &= ~PLL_BASE_BYPASS;
+ if (pll->flags & TEGRA_PLL_BYPASS)
+ val &= ~PLL_BASE_BYPASS;
val |= PLL_BASE_ENABLE;
pll_writel_base(val, pll);
val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
}
-
- clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
- pll->params->lock_bit_idx);
-
- return 0;
}
static void _clk_pll_disable(struct clk_hw *hw)
u32 val;
val = pll_readl_base(pll);
- val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+ if (pll->flags & TEGRA_PLL_BYPASS)
+ val &= ~PLL_BASE_BYPASS;
+ val &= ~PLL_BASE_ENABLE;
pll_writel_base(val, pll);
if (pll->flags & TEGRA_PLLM) {
if (pll->lock)
spin_lock_irqsave(pll->lock, flags);
- ret = _clk_pll_enable(hw);
+ _clk_pll_enable(hw);
+
+ ret = clk_pll_wait_for_lock(pll);
if (pll->lock)
spin_unlock_irqrestore(pll->lock, flags);
if (sel->input_rate == 0)
return -EINVAL;
- BUG_ON(sel->p < 1);
-
cfg->input_rate = sel->input_rate;
cfg->output_rate = sel->output_rate;
cfg->m = sel->m;
unsigned long rate, unsigned long parent_rate)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
+ struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
unsigned long cfreq;
u32 p_div = 0;
cfg->output_rate <<= 1)
p_div++;
- cfg->p = 1 << p_div;
cfg->m = parent_rate / cfreq;
cfg->n = cfg->output_rate / cfreq;
cfg->cpcon = OUT_OF_TABLE_CPCON;
if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) ||
- cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) {
+ (1 << p_div) > divp_max(pll)
+ || cfg->output_rate > pll->params->vco_max) {
pr_err("%s: Failed to set %s rate %lu\n",
__func__, __clk_get_name(hw->clk), rate);
return -EINVAL;
}
+ if (p_tohw) {
+ p_div = 1 << p_div;
+ while (p_tohw->pdiv) {
+ if (p_div <= p_tohw->pdiv) {
+ cfg->p = p_tohw->hw_val;
+ break;
+ }
+ p_tohw++;
+ }
+ if (!p_tohw->pdiv)
+ return -EINVAL;
+ } else
+ cfg->p = p_div;
+
return 0;
}
-static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
- unsigned long rate)
+static void _update_pll_mnp(struct tegra_clk_pll *pll,
+ struct tegra_clk_pll_freq_table *cfg)
{
- struct tegra_clk_pll *pll = to_clk_pll(hw);
- unsigned long flags = 0;
- u32 divp, val, old_base;
- int state;
-
- divp = __ffs(cfg->p);
-
- if (pll->flags & TEGRA_PLLU)
- divp ^= 1;
+ u32 val;
- if (pll->lock)
- spin_lock_irqsave(pll->lock, flags);
+ val = pll_readl_base(pll);
- old_base = val = pll_readl_base(pll);
val &= ~((divm_mask(pll) << pll->divm_shift) |
(divn_mask(pll) << pll->divn_shift) |
(divp_mask(pll) << pll->divp_shift));
val |= ((cfg->m << pll->divm_shift) |
(cfg->n << pll->divn_shift) |
- (divp << pll->divp_shift));
- if (val == old_base) {
- if (pll->lock)
- spin_unlock_irqrestore(pll->lock, flags);
- return 0;
+ (cfg->p << pll->divp_shift));
+
+ pll_writel_base(val, pll);
+}
+
+static void _get_pll_mnp(struct tegra_clk_pll *pll,
+ struct tegra_clk_pll_freq_table *cfg)
+{
+ u32 val;
+
+ val = pll_readl_base(pll);
+
+ cfg->m = (val >> pll->divm_shift) & (divm_mask(pll));
+ cfg->n = (val >> pll->divn_shift) & (divn_mask(pll));
+ cfg->p = (val >> pll->divp_shift) & (divp_mask(pll));
+}
+
+static void _update_pll_cpcon(struct tegra_clk_pll *pll,
+ struct tegra_clk_pll_freq_table *cfg,
+ unsigned long rate)
+{
+ u32 val;
+
+ val = pll_readl_misc(pll);
+
+ val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
+ val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
+
+ if (pll->flags & TEGRA_PLL_SET_LFCON) {
+ val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
+ if (cfg->n >= PLLDU_LFCON_SET_DIVN)
+ val |= 1 << PLL_MISC_LFCON_SHIFT;
+ } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
+ val &= ~(1 << PLL_MISC_DCCON_SHIFT);
+ if (rate >= (pll->params->vco_max >> 1))
+ val |= 1 << PLL_MISC_DCCON_SHIFT;
}
+ pll_writel_misc(val, pll);
+}
+
+static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
+ unsigned long rate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ int state, ret = 0;
+
state = clk_pll_is_enabled(hw);
- if (state) {
+ if (state)
_clk_pll_disable(hw);
- val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
- }
- pll_writel_base(val, pll);
- if (pll->flags & TEGRA_PLL_HAS_CPCON) {
- val = pll_readl_misc(pll);
- val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
- val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
- if (pll->flags & TEGRA_PLL_SET_LFCON) {
- val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
- if (cfg->n >= PLLDU_LFCON_SET_DIVN)
- val |= 0x1 << PLL_MISC_LFCON_SHIFT;
- } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
- val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
- if (rate >= (pll->params->vco_max >> 1))
- val |= 0x1 << PLL_MISC_DCCON_SHIFT;
- }
- pll_writel_misc(val, pll);
- }
+ _update_pll_mnp(pll, cfg);
- if (pll->lock)
- spin_unlock_irqrestore(pll->lock, flags);
+ if (pll->flags & TEGRA_PLL_HAS_CPCON)
+ _update_pll_cpcon(pll, cfg, rate);
- if (state)
- clk_pll_enable(hw);
+ if (state) {
+ _clk_pll_enable(hw);
+ ret = clk_pll_wait_for_lock(pll);
+ }
- return 0;
+ return ret;
}
static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
- struct tegra_clk_pll_freq_table cfg;
+ struct tegra_clk_pll_freq_table cfg, old_cfg;
+ unsigned long flags = 0;
+ int ret = 0;
if (pll->flags & TEGRA_PLL_FIXED) {
if (rate != pll->fixed_rate) {
_calc_rate(hw, &cfg, rate, parent_rate))
return -EINVAL;
- return _program_pll(hw, &cfg, rate);
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _get_pll_mnp(pll, &old_cfg);
+
+ if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p)
+ ret = _program_pll(hw, &cfg, rate);
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
}
static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
return -EINVAL;
output_rate *= cfg.n;
- do_div(output_rate, cfg.m * cfg.p);
+ do_div(output_rate, cfg.m * (1 << cfg.p));
return output_rate;
}
unsigned long parent_rate)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
- u32 val = pll_readl_base(pll);
- u32 divn = 0, divm = 0, divp = 0;
+ struct tegra_clk_pll_freq_table cfg;
+ struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
+ u32 val;
u64 rate = parent_rate;
+ int pdiv;
+
+ val = pll_readl_base(pll);
- if (val & PLL_BASE_BYPASS)
+ if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS))
return parent_rate;
if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) {
return pll->fixed_rate;
}
- divp = (val >> pll->divp_shift) & (divp_mask(pll));
- if (pll->flags & TEGRA_PLLU)
- divp ^= 1;
+ _get_pll_mnp(pll, &cfg);
- divn = (val >> pll->divn_shift) & (divn_mask(pll));
- divm = (val >> pll->divm_shift) & (divm_mask(pll));
- divm *= (1 << divp);
+ if (p_tohw) {
+ while (p_tohw->pdiv) {
+ if (cfg.p == p_tohw->hw_val) {
+ pdiv = p_tohw->pdiv;
+ break;
+ }
+ p_tohw++;
+ }
+
+ if (!p_tohw->pdiv) {
+ WARN_ON(1);
+ pdiv = 1;
+ }
+ } else
+ pdiv = 1 << cfg.p;
+
+ cfg.m *= pdiv;
+
+ rate *= cfg.n;
+ do_div(rate, cfg.m);
- rate *= divn;
- do_div(rate, divm);
return rate;
}
val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
pll_writel_base(val, pll);
- clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg,
- pll->params->lock_bit_idx);
+ clk_pll_wait_for_lock(pll);
+
return 0;
}
.enable = clk_plle_enable,
};
-static struct clk *_tegra_clk_register_pll(const char *name,
- const char *parent_name, void __iomem *clk_base,
- void __iomem *pmc, unsigned long flags,
- unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
- struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock,
- const struct clk_ops *ops)
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+
+static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
+ unsigned long parent_rate)
{
- struct tegra_clk_pll *pll;
- struct clk *clk;
- struct clk_init_data init;
+ if (parent_rate > pll_params->cf_max)
+ return 2;
+ else
+ return 1;
+}
- pll = kzalloc(sizeof(*pll), GFP_KERNEL);
- if (!pll)
- return ERR_PTR(-ENOMEM);
+static int clk_pll_iddq_enable(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
- init.name = name;
- init.ops = ops;
- init.flags = flags;
- init.parent_names = (parent_name ? &parent_name : NULL);
- init.num_parents = (parent_name ? 1 : 0);
+ u32 val;
+ int ret;
- pll->clk_base = clk_base;
- pll->pmc = pmc;
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
- pll->freq_table = freq_table;
- pll->params = pll_params;
- pll->fixed_rate = fixed_rate;
- pll->flags = pll_flags;
- pll->lock = lock;
+ val = pll_readl(pll->params->iddq_reg, pll);
+ val &= ~BIT(pll->params->iddq_bit_idx);
+ pll_writel(val, pll->params->iddq_reg, pll);
+ udelay(2);
- pll->divp_shift = PLL_BASE_DIVP_SHIFT;
- pll->divp_width = PLL_BASE_DIVP_WIDTH;
- pll->divn_shift = PLL_BASE_DIVN_SHIFT;
- pll->divn_width = PLL_BASE_DIVN_WIDTH;
- pll->divm_shift = PLL_BASE_DIVM_SHIFT;
- pll->divm_width = PLL_BASE_DIVM_WIDTH;
+ _clk_pll_enable(hw);
- /* Data in .init is copied by clk_register(), so stack variable OK */
- pll->hw.init = &init;
+ ret = clk_pll_wait_for_lock(pll);
- clk = clk_register(NULL, &pll->hw);
- if (IS_ERR(clk))
- kfree(pll);
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
- return clk;
+ return 0;
}
-struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
- struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+static void clk_pll_iddq_disable(struct clk_hw *hw)
{
- return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
- flags, fixed_rate, pll_params, pll_flags, freq_table,
- lock, &tegra_clk_pll_ops);
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
+ u32 val;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _clk_pll_disable(hw);
+
+ val = pll_readl(pll->params->iddq_reg, pll);
+ val |= BIT(pll->params->iddq_bit_idx);
+ pll_writel(val, pll->params->iddq_reg, pll);
+ udelay(2);
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
}
-struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
- struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+static int _calc_dynamic_ramp_rate(struct clk_hw *hw,
+ struct tegra_clk_pll_freq_table *cfg,
+ unsigned long rate, unsigned long parent_rate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned int p;
+
+ if (!rate)
+ return -EINVAL;
+
+ p = DIV_ROUND_UP(pll->params->vco_min, rate);
+ cfg->m = _pll_fixed_mdiv(pll->params, parent_rate);
+ cfg->p = p;
+ cfg->output_rate = rate * cfg->p;
+ cfg->n = cfg->output_rate * cfg->m / parent_rate;
+
+ if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int _pll_ramp_calc_pll(struct clk_hw *hw,
+ struct tegra_clk_pll_freq_table *cfg,
+ unsigned long rate, unsigned long parent_rate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ int err = 0;
+
+ err = _get_table_rate(hw, cfg, rate, parent_rate);
+ if (err < 0)
+ err = _calc_dynamic_ramp_rate(hw, cfg, rate, parent_rate);
+ else if (cfg->m != _pll_fixed_mdiv(pll->params, parent_rate)) {
+ WARN_ON(1);
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (!cfg->p || (cfg->p > pll->params->max_p))
+ err = -EINVAL;
+
+out:
+ return err;
+}
+
+static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ struct tegra_clk_pll_freq_table cfg, old_cfg;
+ unsigned long flags = 0;
+ int ret = 0;
+ u8 old_p;
+
+ ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
+ if (ret < 0)
+ return ret;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _get_pll_mnp(pll, &old_cfg);
+
+ old_p = pllxc_p[old_cfg.p];
+ if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_p != cfg.p) {
+ cfg.p -= 1;
+ ret = _program_pll(hw, &cfg, rate);
+ }
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
+}
+
+static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct tegra_clk_pll_freq_table cfg;
+ int ret = 0;
+ u64 output_rate = *prate;
+
+ ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate);
+ if (ret < 0)
+ return ret;
+
+ output_rate *= cfg.n;
+ do_div(output_rate, cfg.m * cfg.p);
+
+ return output_rate;
+}
+
+static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll_freq_table cfg;
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
+ int state, ret = 0;
+ u32 val;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ state = clk_pll_is_enabled(hw);
+ if (state) {
+ if (rate != clk_get_rate(hw->clk)) {
+ pr_err("%s: Cannot change active PLLM\n", __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+ goto out;
+ }
+
+ ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
+ if (ret < 0)
+ goto out;
+
+ cfg.p -= 1;
+
+ val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
+ if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) {
+ val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
+ val = cfg.p ? (val | PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK) :
+ (val & ~PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK);
+ writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
+
+ val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
+ val &= ~(divn_mask(pll) | divm_mask(pll));
+ val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift);
+ writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE);
+ } else
+ _update_pll_mnp(pll, &cfg);
+
+
+out:
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
+}
+
+static void _pllcx_strobe(struct tegra_clk_pll *pll)
+{
+ u32 val;
+
+ val = pll_readl_misc(pll);
+ val |= PLLCX_MISC_STROBE;
+ pll_writel_misc(val, pll);
+ udelay(2);
+
+ val &= ~PLLCX_MISC_STROBE;
+ pll_writel_misc(val, pll);
+}
+
+static int clk_pllc_enable(struct clk_hw *hw)
{
- return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
- flags, fixed_rate, pll_params, pll_flags, freq_table,
- lock, &tegra_clk_plle_ops);
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u32 val;
+ int ret = 0;
+ unsigned long flags = 0;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _clk_pll_enable(hw);
+ udelay(2);
+
+ val = pll_readl_misc(pll);
+ val &= ~PLLCX_MISC_RESET;
+ pll_writel_misc(val, pll);
+ udelay(2);
+
+ _pllcx_strobe(pll);
+
+ ret = clk_pll_wait_for_lock(pll);
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
+}
+
+static void _clk_pllc_disable(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u32 val;
+
+ _clk_pll_disable(hw);
+
+ val = pll_readl_misc(pll);
+ val |= PLLCX_MISC_RESET;
+ pll_writel_misc(val, pll);
+ udelay(2);
+}
+
+static void clk_pllc_disable(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _clk_pllc_disable(hw);
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static int _pllcx_update_dynamic_coef(struct tegra_clk_pll *pll,
+ unsigned long input_rate, u32 n)
+{
+ u32 val, n_threshold;
+
+ switch (input_rate) {
+ case 12000000:
+ n_threshold = 70;
+ break;
+ case 13000000:
+ case 26000000:
+ n_threshold = 71;
+ break;
+ case 16800000:
+ n_threshold = 55;
+ break;
+ case 19200000:
+ n_threshold = 48;
+ break;
+ default:
+ pr_err("%s: Unexpected reference rate %lu\n",
+ __func__, input_rate);
+ return -EINVAL;
+ }
+
+ val = pll_readl_misc(pll);
+ val &= ~(PLLCX_MISC_SDM_DIV_MASK | PLLCX_MISC_FILT_DIV_MASK);
+ val |= n <= n_threshold ?
+ PLLCX_MISC_DIV_LOW_RANGE : PLLCX_MISC_DIV_HIGH_RANGE;
+ pll_writel_misc(val, pll);
+
+ return 0;
+}
+
+static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll_freq_table cfg;
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
+ int state, ret = 0;
+ u32 val;
+ u16 old_m, old_n;
+ u8 old_p;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
+ if (ret < 0)
+ goto out;
+
+ val = pll_readl_base(pll);
+ old_m = (val >> pll->divm_shift) & (divm_mask(pll));
+ old_n = (val >> pll->divn_shift) & (divn_mask(pll));
+ old_p = pllcx_p[(val >> pll->divp_shift) & (divp_mask(pll))];
+
+ if (cfg.m != old_m) {
+ WARN_ON(1);
+ goto out;
+ }
+
+ if (old_n == cfg.n && old_p == cfg.p)
+ goto out;
+
+ cfg.p -= 1;
+
+ state = clk_pll_is_enabled(hw);
+ if (state)
+ _clk_pllc_disable(hw);
+
+ ret = _pllcx_update_dynamic_coef(pll, parent_rate, cfg.n);
+ if (ret < 0)
+ goto out;
+
+ _update_pll_mnp(pll, &cfg);
+
+ if (state)
+ ret = clk_pllc_enable(hw);
+
+out:
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
+}
+
+static long _pllre_calc_rate(struct tegra_clk_pll *pll,
+ struct tegra_clk_pll_freq_table *cfg,
+ unsigned long rate, unsigned long parent_rate)
+{
+ u16 m, n;
+ u64 output_rate = parent_rate;
+
+ m = _pll_fixed_mdiv(pll->params, parent_rate);
+ n = rate * m / parent_rate;
+
+ output_rate *= n;
+ do_div(output_rate, m);
+
+ if (cfg) {
+ cfg->m = m;
+ cfg->n = n;
+ }
+
+ return output_rate;
+}
+static int clk_pllre_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll_freq_table cfg, old_cfg;
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
+ int state, ret = 0;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _pllre_calc_rate(pll, &cfg, rate, parent_rate);
+ _get_pll_mnp(pll, &old_cfg);
+ cfg.p = old_cfg.p;
+
+ if (cfg.m != old_cfg.m || cfg.n != old_cfg.n) {
+ state = clk_pll_is_enabled(hw);
+ if (state)
+ _clk_pll_disable(hw);
+
+ _update_pll_mnp(pll, &cfg);
+
+ if (state) {
+ _clk_pll_enable(hw);
+ ret = clk_pll_wait_for_lock(pll);
+ }
+ }
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
+}
+
+static unsigned long clk_pllre_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll_freq_table cfg;
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u64 rate = parent_rate;
+
+ _get_pll_mnp(pll, &cfg);
+
+ rate *= cfg.n;
+ do_div(rate, cfg.m);
+
+ return rate;
+}
+
+static long clk_pllre_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+
+ return _pllre_calc_rate(pll, NULL, rate, *prate);
+}
+
+static int clk_plle_tegra114_enable(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ struct tegra_clk_pll_freq_table sel;
+ u32 val;
+ int ret;
+ unsigned long flags = 0;
+ unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk));
+
+ if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
+ return -EINVAL;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ val = pll_readl_base(pll);
+ val &= ~BIT(29); /* Disable lock override */
+ pll_writel_base(val, pll);
+
+ val = pll_readl(pll->params->aux_reg, pll);
+ val |= PLLE_AUX_ENABLE_SWCTL;
+ val &= ~PLLE_AUX_SEQ_ENABLE;
+ pll_writel(val, pll->params->aux_reg, pll);
+ udelay(1);
+
+ val = pll_readl_misc(pll);
+ val |= PLLE_MISC_LOCK_ENABLE;
+ val |= PLLE_MISC_IDDQ_SW_CTRL;
+ val &= ~PLLE_MISC_IDDQ_SW_VALUE;
+ val |= PLLE_MISC_PLLE_PTS;
+ val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK;
+ pll_writel_misc(val, pll);
+ udelay(5);
+
+ val = pll_readl(PLLE_SS_CTRL, pll);
+ val |= PLLE_SS_DISABLE;
+ pll_writel(val, PLLE_SS_CTRL, pll);
+
+ val = pll_readl_base(pll);
+ val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
+ val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
+ val |= sel.m << pll->divm_shift;
+ val |= sel.n << pll->divn_shift;
+ val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
+ pll_writel_base(val, pll);
+ udelay(1);
+
+ _clk_pll_enable(hw);
+ ret = clk_pll_wait_for_lock(pll);
+
+ if (ret < 0)
+ goto out;
+
+ /* TODO: enable hw control of xusb brick pll */
+
+out:
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+
+ return ret;
+}
+
+static void clk_plle_tegra114_disable(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long flags = 0;
+ u32 val;
+
+ if (pll->lock)
+ spin_lock_irqsave(pll->lock, flags);
+
+ _clk_pll_disable(hw);
+
+ val = pll_readl_misc(pll);
+ val |= PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE;
+ pll_writel_misc(val, pll);
+ udelay(1);
+
+ if (pll->lock)
+ spin_unlock_irqrestore(pll->lock, flags);
+}
+#endif
+
+static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
+ void __iomem *pmc, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+{
+ struct tegra_clk_pll *pll;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->clk_base = clk_base;
+ pll->pmc = pmc;
+
+ pll->freq_table = freq_table;
+ pll->params = pll_params;
+ pll->fixed_rate = fixed_rate;
+ pll->flags = pll_flags;
+ pll->lock = lock;
+
+ pll->divp_shift = PLL_BASE_DIVP_SHIFT;
+ pll->divp_width = PLL_BASE_DIVP_WIDTH;
+ pll->divn_shift = PLL_BASE_DIVN_SHIFT;
+ pll->divn_width = PLL_BASE_DIVN_WIDTH;
+ pll->divm_shift = PLL_BASE_DIVM_SHIFT;
+ pll->divm_width = PLL_BASE_DIVM_WIDTH;
+
+ return pll;
+}
+
+static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
+ const char *name, const char *parent_name, unsigned long flags,
+ const struct clk_ops *ops)
+{
+ struct clk_init_data init;
+
+ init.name = name;
+ init.ops = ops;
+ init.flags = flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ /* Data in .init is copied by clk_register(), so stack variable OK */
+ pll->hw.init = &init;
+
+ return clk_register(NULL, &pll->hw);
+}
+
+struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+{
+ struct tegra_clk_pll *pll;
+ struct clk *clk;
+
+ pll_flags |= TEGRA_PLL_BYPASS;
+ pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+ pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+ freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_pll_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+{
+ struct tegra_clk_pll *pll;
+ struct clk *clk;
+
+ pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS;
+ pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+ pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+ freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_plle_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+const struct clk_ops tegra_clk_pllxc_ops = {
+ .is_enabled = clk_pll_is_enabled,
+ .enable = clk_pll_iddq_enable,
+ .disable = clk_pll_iddq_disable,
+ .recalc_rate = clk_pll_recalc_rate,
+ .round_rate = clk_pll_ramp_round_rate,
+ .set_rate = clk_pllxc_set_rate,
+};
+
+const struct clk_ops tegra_clk_pllm_ops = {
+ .is_enabled = clk_pll_is_enabled,
+ .enable = clk_pll_iddq_enable,
+ .disable = clk_pll_iddq_disable,
+ .recalc_rate = clk_pll_recalc_rate,
+ .round_rate = clk_pll_ramp_round_rate,
+ .set_rate = clk_pllm_set_rate,
+};
+
+const struct clk_ops tegra_clk_pllc_ops = {
+ .is_enabled = clk_pll_is_enabled,
+ .enable = clk_pllc_enable,
+ .disable = clk_pllc_disable,
+ .recalc_rate = clk_pll_recalc_rate,
+ .round_rate = clk_pll_ramp_round_rate,
+ .set_rate = clk_pllc_set_rate,
+};
+
+const struct clk_ops tegra_clk_pllre_ops = {
+ .is_enabled = clk_pll_is_enabled,
+ .enable = clk_pll_iddq_enable,
+ .disable = clk_pll_iddq_disable,
+ .recalc_rate = clk_pllre_recalc_rate,
+ .round_rate = clk_pllre_round_rate,
+ .set_rate = clk_pllre_set_rate,
+};
+
+const struct clk_ops tegra_clk_plle_tegra114_ops = {
+ .is_enabled = clk_pll_is_enabled,
+ .enable = clk_plle_tegra114_enable,
+ .disable = clk_plle_tegra114_disable,
+ .recalc_rate = clk_pll_recalc_rate,
+};
+
+
+struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock)
+{
+ struct tegra_clk_pll *pll;
+ struct clk *clk;
+
+ if (!pll_params->pdiv_tohw)
+ return ERR_PTR(-EINVAL);
+
+ pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+ pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+ freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_pllxc_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock, unsigned long parent_rate)
+{
+ u32 val;
+ struct tegra_clk_pll *pll;
+ struct clk *clk;
+
+ pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+ pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+ freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ /* program minimum rate by default */
+
+ val = pll_readl_base(pll);
+ if (val & PLL_BASE_ENABLE)
+ WARN_ON(val & pll_params->iddq_bit_idx);
+ else {
+ int m;
+
+ m = _pll_fixed_mdiv(pll_params, parent_rate);
+ val = m << PLL_BASE_DIVM_SHIFT;
+ val |= (pll_params->vco_min / parent_rate)
+ << PLL_BASE_DIVN_SHIFT;
+ pll_writel_base(val, pll);
+ }
+
+ /* disable lock override */
+
+ val = pll_readl_misc(pll);
+ val &= ~BIT(29);
+ pll_writel_misc(val, pll);
+
+ pll_flags |= TEGRA_PLL_LOCK_MISC;
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_pllre_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock)
+{
+ struct tegra_clk_pll *pll;
+ struct clk *clk;
+
+ if (!pll_params->pdiv_tohw)
+ return ERR_PTR(-EINVAL);
+
+ pll_flags |= TEGRA_PLL_BYPASS;
+ pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+ pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+ freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_pllm_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock)
+{
+ struct clk *parent, *clk;
+ struct pdiv_map *p_tohw = pll_params->pdiv_tohw;
+ struct tegra_clk_pll *pll;
+ struct tegra_clk_pll_freq_table cfg;
+ unsigned long parent_rate;
+
+ if (!p_tohw)
+ return ERR_PTR(-EINVAL);
+
+ parent = __clk_lookup(parent_name);
+ if (IS_ERR(parent)) {
+ WARN(1, "parent clk %s of %s must be registered first\n",
+ name, parent_name);
+ return ERR_PTR(-EINVAL);
+ }
+
+ pll_flags |= TEGRA_PLL_BYPASS;
+ pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+ freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ parent_rate = __clk_get_rate(parent);
+
+ /*
+ * Most of PLLC register fields are shadowed, and can not be read
+ * directly from PLL h/w. Hence, actual PLLC boot state is unknown.
+ * Initialize PLL to default state: disabled, reset; shadow registers
+ * loaded with default parameters; dividers are preset for half of
+ * minimum VCO rate (the latter assured that shadowed divider settings
+ * are within supported range).
+ */
+
+ cfg.m = _pll_fixed_mdiv(pll_params, parent_rate);
+ cfg.n = cfg.m * pll_params->vco_min / parent_rate;
+
+ while (p_tohw->pdiv) {
+ if (p_tohw->pdiv == 2) {
+ cfg.p = p_tohw->hw_val;
+ break;
+ }
+ p_tohw++;
+ }
+
+ if (!p_tohw->pdiv) {
+ WARN_ON(1);
+ return ERR_PTR(-EINVAL);
+ }
+
+ pll_writel_base(0, pll);
+ _update_pll_mnp(pll, &cfg);
+
+ pll_writel_misc(PLLCX_MISC_DEFAULT, pll);
+ pll_writel(PLLCX_MISC1_DEFAULT, pll_params->ext_misc_reg[0], pll);
+ pll_writel(PLLCX_MISC2_DEFAULT, pll_params->ext_misc_reg[1], pll);
+ pll_writel(PLLCX_MISC3_DEFAULT, pll_params->ext_misc_reg[2], pll);
+
+ _pllcx_update_dynamic_coef(pll, parent_rate, cfg.n);
+
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_pllc_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
+
+struct clk *tegra_clk_register_plle_tegra114(const char *name,
+ const char *parent_name,
+ void __iomem *clk_base, unsigned long flags,
+ unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock)
+{
+ struct tegra_clk_pll *pll;
+ struct clk *clk;
+ u32 val, val_aux;
+
+ pll = _tegra_init_pll(clk_base, NULL, fixed_rate, pll_params,
+ TEGRA_PLL_HAS_LOCK_ENABLE, freq_table, lock);
+ if (IS_ERR(pll))
+ return ERR_CAST(pll);
+
+ /* ensure parent is set to pll_re_vco */
+
+ val = pll_readl_base(pll);
+ val_aux = pll_readl(pll_params->aux_reg, pll);
+
+ if (val & PLL_BASE_ENABLE) {
+ if (!(val_aux & PLLE_AUX_PLLRE_SEL))
+ WARN(1, "pll_e enabled with unsupported parent %s\n",
+ (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref");
+ } else {
+ val_aux |= PLLE_AUX_PLLRE_SEL;
+ pll_writel(val, pll_params->aux_reg, pll);
+ }
+
+ clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+ &tegra_clk_plle_tegra114_ops);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/delay.h>
+#include <linux/clk/tegra.h>
+
+#include "clk.h"
+
+#define RST_DEVICES_L 0x004
+#define RST_DEVICES_H 0x008
+#define RST_DEVICES_U 0x00C
+#define RST_DEVICES_V 0x358
+#define RST_DEVICES_W 0x35C
+#define RST_DEVICES_X 0x28C
+#define RST_DEVICES_SET_L 0x300
+#define RST_DEVICES_CLR_L 0x304
+#define RST_DEVICES_SET_H 0x308
+#define RST_DEVICES_CLR_H 0x30c
+#define RST_DEVICES_SET_U 0x310
+#define RST_DEVICES_CLR_U 0x314
+#define RST_DEVICES_SET_V 0x430
+#define RST_DEVICES_CLR_V 0x434
+#define RST_DEVICES_SET_W 0x438
+#define RST_DEVICES_CLR_W 0x43c
+#define RST_DEVICES_NUM 5
+
+#define CLK_OUT_ENB_L 0x010
+#define CLK_OUT_ENB_H 0x014
+#define CLK_OUT_ENB_U 0x018
+#define CLK_OUT_ENB_V 0x360
+#define CLK_OUT_ENB_W 0x364
+#define CLK_OUT_ENB_X 0x280
+#define CLK_OUT_ENB_SET_L 0x320
+#define CLK_OUT_ENB_CLR_L 0x324
+#define CLK_OUT_ENB_SET_H 0x328
+#define CLK_OUT_ENB_CLR_H 0x32c
+#define CLK_OUT_ENB_SET_U 0x330
+#define CLK_OUT_ENB_CLR_U 0x334
+#define CLK_OUT_ENB_SET_V 0x440
+#define CLK_OUT_ENB_CLR_V 0x444
+#define CLK_OUT_ENB_SET_W 0x448
+#define CLK_OUT_ENB_CLR_W 0x44c
+#define CLK_OUT_ENB_SET_X 0x284
+#define CLK_OUT_ENB_CLR_X 0x288
+#define CLK_OUT_ENB_NUM 6
+
+#define PLLC_BASE 0x80
+#define PLLC_MISC2 0x88
+#define PLLC_MISC 0x8c
+#define PLLC2_BASE 0x4e8
+#define PLLC2_MISC 0x4ec
+#define PLLC3_BASE 0x4fc
+#define PLLC3_MISC 0x500
+#define PLLM_BASE 0x90
+#define PLLM_MISC 0x9c
+#define PLLP_BASE 0xa0
+#define PLLP_MISC 0xac
+#define PLLX_BASE 0xe0
+#define PLLX_MISC 0xe4
+#define PLLX_MISC2 0x514
+#define PLLX_MISC3 0x518
+#define PLLD_BASE 0xd0
+#define PLLD_MISC 0xdc
+#define PLLD2_BASE 0x4b8
+#define PLLD2_MISC 0x4bc
+#define PLLE_BASE 0xe8
+#define PLLE_MISC 0xec
+#define PLLA_BASE 0xb0
+#define PLLA_MISC 0xbc
+#define PLLU_BASE 0xc0
+#define PLLU_MISC 0xcc
+#define PLLRE_BASE 0x4c4
+#define PLLRE_MISC 0x4c8
+
+#define PLL_MISC_LOCK_ENABLE 18
+#define PLLC_MISC_LOCK_ENABLE 24
+#define PLLDU_MISC_LOCK_ENABLE 22
+#define PLLE_MISC_LOCK_ENABLE 9
+#define PLLRE_MISC_LOCK_ENABLE 30
+
+#define PLLC_IDDQ_BIT 26
+#define PLLX_IDDQ_BIT 3
+#define PLLRE_IDDQ_BIT 16
+
+#define PLL_BASE_LOCK BIT(27)
+#define PLLE_MISC_LOCK BIT(11)
+#define PLLRE_MISC_LOCK BIT(24)
+#define PLLCX_BASE_LOCK (BIT(26)|BIT(27))
+
+#define PLLE_AUX 0x48c
+#define PLLC_OUT 0x84
+#define PLLM_OUT 0x94
+#define PLLP_OUTA 0xa4
+#define PLLP_OUTB 0xa8
+#define PLLA_OUT 0xb4
+
+#define AUDIO_SYNC_CLK_I2S0 0x4a0
+#define AUDIO_SYNC_CLK_I2S1 0x4a4
+#define AUDIO_SYNC_CLK_I2S2 0x4a8
+#define AUDIO_SYNC_CLK_I2S3 0x4ac
+#define AUDIO_SYNC_CLK_I2S4 0x4b0
+#define AUDIO_SYNC_CLK_SPDIF 0x4b4
+
+#define AUDIO_SYNC_DOUBLER 0x49c
+
+#define PMC_CLK_OUT_CNTRL 0x1a8
+#define PMC_DPD_PADS_ORIDE 0x1c
+#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20
+#define PMC_CTRL 0
+#define PMC_CTRL_BLINK_ENB 7
+
+#define OSC_CTRL 0x50
+#define OSC_CTRL_OSC_FREQ_SHIFT 28
+#define OSC_CTRL_PLL_REF_DIV_SHIFT 26
+
+#define PLLXC_SW_MAX_P 6
+
+#define CCLKG_BURST_POLICY 0x368
+#define CCLKLP_BURST_POLICY 0x370
+#define SCLK_BURST_POLICY 0x028
+#define SYSTEM_CLK_RATE 0x030
+
+#define UTMIP_PLL_CFG2 0x488
+#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6)
+#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4)
+
+#define UTMIP_PLL_CFG1 0x484
+#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6)
+#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
+
+#define UTMIPLL_HW_PWRDN_CFG0 0x52c
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25)
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24)
+#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6)
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5)
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4)
+#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2)
+#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1)
+#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0)
+
+#define CLK_SOURCE_I2S0 0x1d8
+#define CLK_SOURCE_I2S1 0x100
+#define CLK_SOURCE_I2S2 0x104
+#define CLK_SOURCE_NDFLASH 0x160
+#define CLK_SOURCE_I2S3 0x3bc
+#define CLK_SOURCE_I2S4 0x3c0
+#define CLK_SOURCE_SPDIF_OUT 0x108
+#define CLK_SOURCE_SPDIF_IN 0x10c
+#define CLK_SOURCE_PWM 0x110
+#define CLK_SOURCE_ADX 0x638
+#define CLK_SOURCE_AMX 0x63c
+#define CLK_SOURCE_HDA 0x428
+#define CLK_SOURCE_HDA2CODEC_2X 0x3e4
+#define CLK_SOURCE_SBC1 0x134
+#define CLK_SOURCE_SBC2 0x118
+#define CLK_SOURCE_SBC3 0x11c
+#define CLK_SOURCE_SBC4 0x1b4
+#define CLK_SOURCE_SBC5 0x3c8
+#define CLK_SOURCE_SBC6 0x3cc
+#define CLK_SOURCE_SATA_OOB 0x420
+#define CLK_SOURCE_SATA 0x424
+#define CLK_SOURCE_NDSPEED 0x3f8
+#define CLK_SOURCE_VFIR 0x168
+#define CLK_SOURCE_SDMMC1 0x150
+#define CLK_SOURCE_SDMMC2 0x154
+#define CLK_SOURCE_SDMMC3 0x1bc
+#define CLK_SOURCE_SDMMC4 0x164
+#define CLK_SOURCE_VDE 0x1c8
+#define CLK_SOURCE_CSITE 0x1d4
+#define CLK_SOURCE_LA 0x1f8
+#define CLK_SOURCE_TRACE 0x634
+#define CLK_SOURCE_OWR 0x1cc
+#define CLK_SOURCE_NOR 0x1d0
+#define CLK_SOURCE_MIPI 0x174
+#define CLK_SOURCE_I2C1 0x124
+#define CLK_SOURCE_I2C2 0x198
+#define CLK_SOURCE_I2C3 0x1b8
+#define CLK_SOURCE_I2C4 0x3c4
+#define CLK_SOURCE_I2C5 0x128
+#define CLK_SOURCE_UARTA 0x178
+#define CLK_SOURCE_UARTB 0x17c
+#define CLK_SOURCE_UARTC 0x1a0
+#define CLK_SOURCE_UARTD 0x1c0
+#define CLK_SOURCE_UARTE 0x1c4
+#define CLK_SOURCE_UARTA_DBG 0x178
+#define CLK_SOURCE_UARTB_DBG 0x17c
+#define CLK_SOURCE_UARTC_DBG 0x1a0
+#define CLK_SOURCE_UARTD_DBG 0x1c0
+#define CLK_SOURCE_UARTE_DBG 0x1c4
+#define CLK_SOURCE_3D 0x158
+#define CLK_SOURCE_2D 0x15c
+#define CLK_SOURCE_VI_SENSOR 0x1a8
+#define CLK_SOURCE_VI 0x148
+#define CLK_SOURCE_EPP 0x16c
+#define CLK_SOURCE_MSENC 0x1f0
+#define CLK_SOURCE_TSEC 0x1f4
+#define CLK_SOURCE_HOST1X 0x180
+#define CLK_SOURCE_HDMI 0x18c
+#define CLK_SOURCE_DISP1 0x138
+#define CLK_SOURCE_DISP2 0x13c
+#define CLK_SOURCE_CILAB 0x614
+#define CLK_SOURCE_CILCD 0x618
+#define CLK_SOURCE_CILE 0x61c
+#define CLK_SOURCE_DSIALP 0x620
+#define CLK_SOURCE_DSIBLP 0x624
+#define CLK_SOURCE_TSENSOR 0x3b8
+#define CLK_SOURCE_D_AUDIO 0x3d0
+#define CLK_SOURCE_DAM0 0x3d8
+#define CLK_SOURCE_DAM1 0x3dc
+#define CLK_SOURCE_DAM2 0x3e0
+#define CLK_SOURCE_ACTMON 0x3e8
+#define CLK_SOURCE_EXTERN1 0x3ec
+#define CLK_SOURCE_EXTERN2 0x3f0
+#define CLK_SOURCE_EXTERN3 0x3f4
+#define CLK_SOURCE_I2CSLOW 0x3fc
+#define CLK_SOURCE_SE 0x42c
+#define CLK_SOURCE_MSELECT 0x3b4
+#define CLK_SOURCE_SOC_THERM 0x644
+#define CLK_SOURCE_XUSB_HOST_SRC 0x600
+#define CLK_SOURCE_XUSB_FALCON_SRC 0x604
+#define CLK_SOURCE_XUSB_FS_SRC 0x608
+#define CLK_SOURCE_XUSB_SS_SRC 0x610
+#define CLK_SOURCE_XUSB_DEV_SRC 0x60c
+#define CLK_SOURCE_EMC 0x19c
+
+static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
+
+static void __iomem *clk_base;
+static void __iomem *pmc_base;
+
+static DEFINE_SPINLOCK(pll_d_lock);
+static DEFINE_SPINLOCK(pll_d2_lock);
+static DEFINE_SPINLOCK(pll_u_lock);
+static DEFINE_SPINLOCK(pll_div_lock);
+static DEFINE_SPINLOCK(pll_re_lock);
+static DEFINE_SPINLOCK(clk_doubler_lock);
+static DEFINE_SPINLOCK(clk_out_lock);
+static DEFINE_SPINLOCK(sysrate_lock);
+
+static struct pdiv_map pllxc_p[] = {
+ { .pdiv = 1, .hw_val = 0 },
+ { .pdiv = 2, .hw_val = 1 },
+ { .pdiv = 3, .hw_val = 2 },
+ { .pdiv = 4, .hw_val = 3 },
+ { .pdiv = 5, .hw_val = 4 },
+ { .pdiv = 6, .hw_val = 5 },
+ { .pdiv = 8, .hw_val = 6 },
+ { .pdiv = 10, .hw_val = 7 },
+ { .pdiv = 12, .hw_val = 8 },
+ { .pdiv = 16, .hw_val = 9 },
+ { .pdiv = 12, .hw_val = 10 },
+ { .pdiv = 16, .hw_val = 11 },
+ { .pdiv = 20, .hw_val = 12 },
+ { .pdiv = 24, .hw_val = 13 },
+ { .pdiv = 32, .hw_val = 14 },
+ { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
+ { 12000000, 624000000, 104, 0, 2},
+ { 12000000, 600000000, 100, 0, 2},
+ { 13000000, 600000000, 92, 0, 2}, /* actual: 598.0 MHz */
+ { 16800000, 600000000, 71, 0, 2}, /* actual: 596.4 MHz */
+ { 19200000, 600000000, 62, 0, 2}, /* actual: 595.2 MHz */
+ { 26000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct tegra_clk_pll_params pll_c_params = {
+ .input_min = 12000000,
+ .input_max = 800000000,
+ .cf_min = 12000000,
+ .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */
+ .vco_min = 600000000,
+ .vco_max = 1400000000,
+ .base_reg = PLLC_BASE,
+ .misc_reg = PLLC_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLLC_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+ .iddq_reg = PLLC_MISC,
+ .iddq_bit_idx = PLLC_IDDQ_BIT,
+ .max_p = PLLXC_SW_MAX_P,
+ .dyn_ramp_reg = PLLC_MISC2,
+ .stepa_shift = 17,
+ .stepb_shift = 9,
+ .pdiv_tohw = pllxc_p,
+};
+
+static struct pdiv_map pllc_p[] = {
+ { .pdiv = 1, .hw_val = 0 },
+ { .pdiv = 2, .hw_val = 1 },
+ { .pdiv = 4, .hw_val = 3 },
+ { .pdiv = 8, .hw_val = 5 },
+ { .pdiv = 16, .hw_val = 7 },
+ { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = {
+ {12000000, 600000000, 100, 0, 2},
+ {13000000, 600000000, 92, 0, 2}, /* actual: 598.0 MHz */
+ {16800000, 600000000, 71, 0, 2}, /* actual: 596.4 MHz */
+ {19200000, 600000000, 62, 0, 2}, /* actual: 595.2 MHz */
+ {26000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_c2_params = {
+ .input_min = 12000000,
+ .input_max = 48000000,
+ .cf_min = 12000000,
+ .cf_max = 19200000,
+ .vco_min = 600000000,
+ .vco_max = 1200000000,
+ .base_reg = PLLC2_BASE,
+ .misc_reg = PLLC2_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+ .pdiv_tohw = pllc_p,
+ .ext_misc_reg[0] = 0x4f0,
+ .ext_misc_reg[1] = 0x4f4,
+ .ext_misc_reg[2] = 0x4f8,
+};
+
+static struct tegra_clk_pll_params pll_c3_params = {
+ .input_min = 12000000,
+ .input_max = 48000000,
+ .cf_min = 12000000,
+ .cf_max = 19200000,
+ .vco_min = 600000000,
+ .vco_max = 1200000000,
+ .base_reg = PLLC3_BASE,
+ .misc_reg = PLLC3_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+ .pdiv_tohw = pllc_p,
+ .ext_misc_reg[0] = 0x504,
+ .ext_misc_reg[1] = 0x508,
+ .ext_misc_reg[2] = 0x50c,
+};
+
+static struct pdiv_map pllm_p[] = {
+ { .pdiv = 1, .hw_val = 0 },
+ { .pdiv = 2, .hw_val = 1 },
+ { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
+ {12000000, 800000000, 66, 0, 1}, /* actual: 792.0 MHz */
+ {13000000, 800000000, 61, 0, 1}, /* actual: 793.0 MHz */
+ {16800000, 800000000, 47, 0, 1}, /* actual: 789.6 MHz */
+ {19200000, 800000000, 41, 0, 1}, /* actual: 787.2 MHz */
+ {26000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_m_params = {
+ .input_min = 12000000,
+ .input_max = 500000000,
+ .cf_min = 12000000,
+ .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */
+ .vco_min = 400000000,
+ .vco_max = 1066000000,
+ .base_reg = PLLM_BASE,
+ .misc_reg = PLLM_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+ .max_p = 2,
+ .pdiv_tohw = pllm_p,
+};
+
+static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
+ {12000000, 216000000, 432, 12, 1, 8},
+ {13000000, 216000000, 432, 13, 1, 8},
+ {16800000, 216000000, 360, 14, 1, 8},
+ {19200000, 216000000, 360, 16, 1, 8},
+ {26000000, 216000000, 432, 26, 1, 8},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_p_params = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 200000000,
+ .vco_max = 700000000,
+ .base_reg = PLLP_BASE,
+ .misc_reg = PLLP_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+};
+
+static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
+ {9600000, 282240000, 147, 5, 0, 4},
+ {9600000, 368640000, 192, 5, 0, 4},
+ {9600000, 240000000, 200, 8, 0, 8},
+
+ {28800000, 282240000, 245, 25, 0, 8},
+ {28800000, 368640000, 320, 25, 0, 8},
+ {28800000, 240000000, 200, 24, 0, 8},
+ {0, 0, 0, 0, 0, 0},
+};
+
+
+static struct tegra_clk_pll_params pll_a_params = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 200000000,
+ .vco_max = 700000000,
+ .base_reg = PLLA_BASE,
+ .misc_reg = PLLA_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+};
+
+static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
+ {12000000, 216000000, 864, 12, 2, 12},
+ {13000000, 216000000, 864, 13, 2, 12},
+ {16800000, 216000000, 720, 14, 2, 12},
+ {19200000, 216000000, 720, 16, 2, 12},
+ {26000000, 216000000, 864, 26, 2, 12},
+
+ {12000000, 594000000, 594, 12, 0, 12},
+ {13000000, 594000000, 594, 13, 0, 12},
+ {16800000, 594000000, 495, 14, 0, 12},
+ {19200000, 594000000, 495, 16, 0, 12},
+ {26000000, 594000000, 594, 26, 0, 12},
+
+ {12000000, 1000000000, 1000, 12, 0, 12},
+ {13000000, 1000000000, 1000, 13, 0, 12},
+ {19200000, 1000000000, 625, 12, 0, 12},
+ {26000000, 1000000000, 1000, 26, 0, 12},
+
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_d_params = {
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 500000000,
+ .vco_max = 1000000000,
+ .base_reg = PLLD_BASE,
+ .misc_reg = PLLD_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
+ .lock_delay = 1000,
+};
+
+static struct tegra_clk_pll_params pll_d2_params = {
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 500000000,
+ .vco_max = 1000000000,
+ .base_reg = PLLD2_BASE,
+ .misc_reg = PLLD2_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
+ .lock_delay = 1000,
+};
+
+static struct pdiv_map pllu_p[] = {
+ { .pdiv = 1, .hw_val = 1 },
+ { .pdiv = 2, .hw_val = 0 },
+ { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
+ {12000000, 480000000, 960, 12, 0, 12},
+ {13000000, 480000000, 960, 13, 0, 12},
+ {16800000, 480000000, 400, 7, 0, 5},
+ {19200000, 480000000, 200, 4, 0, 3},
+ {26000000, 480000000, 960, 26, 0, 12},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_u_params = {
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 480000000,
+ .vco_max = 960000000,
+ .base_reg = PLLU_BASE,
+ .misc_reg = PLLU_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
+ .lock_delay = 1000,
+ .pdiv_tohw = pllu_p,
+};
+
+static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
+ /* 1 GHz */
+ {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */
+ {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */
+ {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */
+ {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */
+ {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */
+
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_x_params = {
+ .input_min = 12000000,
+ .input_max = 800000000,
+ .cf_min = 12000000,
+ .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */
+ .vco_min = 700000000,
+ .vco_max = 2400000000U,
+ .base_reg = PLLX_BASE,
+ .misc_reg = PLLX_MISC,
+ .lock_mask = PLL_BASE_LOCK,
+ .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+ .iddq_reg = PLLX_MISC3,
+ .iddq_bit_idx = PLLX_IDDQ_BIT,
+ .max_p = PLLXC_SW_MAX_P,
+ .dyn_ramp_reg = PLLX_MISC2,
+ .stepa_shift = 16,
+ .stepb_shift = 24,
+ .pdiv_tohw = pllxc_p,
+};
+
+static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
+ /* PLLE special case: use cpcon field to store cml divider value */
+ {336000000, 100000000, 100, 21, 16, 11},
+ {312000000, 100000000, 200, 26, 24, 13},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_e_params = {
+ .input_min = 12000000,
+ .input_max = 1000000000,
+ .cf_min = 12000000,
+ .cf_max = 75000000,
+ .vco_min = 1600000000,
+ .vco_max = 2400000000U,
+ .base_reg = PLLE_BASE,
+ .misc_reg = PLLE_MISC,
+ .aux_reg = PLLE_AUX,
+ .lock_mask = PLLE_MISC_LOCK,
+ .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+};
+
+static struct tegra_clk_pll_params pll_re_vco_params = {
+ .input_min = 12000000,
+ .input_max = 1000000000,
+ .cf_min = 12000000,
+ .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */
+ .vco_min = 300000000,
+ .vco_max = 600000000,
+ .base_reg = PLLRE_BASE,
+ .misc_reg = PLLRE_MISC,
+ .lock_mask = PLLRE_MISC_LOCK,
+ .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+ .iddq_reg = PLLRE_MISC,
+ .iddq_bit_idx = PLLRE_IDDQ_BIT,
+};
+
+/* Peripheral clock registers */
+
+static struct tegra_clk_periph_regs periph_l_regs = {
+ .enb_reg = CLK_OUT_ENB_L,
+ .enb_set_reg = CLK_OUT_ENB_SET_L,
+ .enb_clr_reg = CLK_OUT_ENB_CLR_L,
+ .rst_reg = RST_DEVICES_L,
+ .rst_set_reg = RST_DEVICES_SET_L,
+ .rst_clr_reg = RST_DEVICES_CLR_L,
+};
+
+static struct tegra_clk_periph_regs periph_h_regs = {
+ .enb_reg = CLK_OUT_ENB_H,
+ .enb_set_reg = CLK_OUT_ENB_SET_H,
+ .enb_clr_reg = CLK_OUT_ENB_CLR_H,
+ .rst_reg = RST_DEVICES_H,
+ .rst_set_reg = RST_DEVICES_SET_H,
+ .rst_clr_reg = RST_DEVICES_CLR_H,
+};
+
+static struct tegra_clk_periph_regs periph_u_regs = {
+ .enb_reg = CLK_OUT_ENB_U,
+ .enb_set_reg = CLK_OUT_ENB_SET_U,
+ .enb_clr_reg = CLK_OUT_ENB_CLR_U,
+ .rst_reg = RST_DEVICES_U,
+ .rst_set_reg = RST_DEVICES_SET_U,
+ .rst_clr_reg = RST_DEVICES_CLR_U,
+};
+
+static struct tegra_clk_periph_regs periph_v_regs = {
+ .enb_reg = CLK_OUT_ENB_V,
+ .enb_set_reg = CLK_OUT_ENB_SET_V,
+ .enb_clr_reg = CLK_OUT_ENB_CLR_V,
+ .rst_reg = RST_DEVICES_V,
+ .rst_set_reg = RST_DEVICES_SET_V,
+ .rst_clr_reg = RST_DEVICES_CLR_V,
+};
+
+static struct tegra_clk_periph_regs periph_w_regs = {
+ .enb_reg = CLK_OUT_ENB_W,
+ .enb_set_reg = CLK_OUT_ENB_SET_W,
+ .enb_clr_reg = CLK_OUT_ENB_CLR_W,
+ .rst_reg = RST_DEVICES_W,
+ .rst_set_reg = RST_DEVICES_SET_W,
+ .rst_clr_reg = RST_DEVICES_CLR_W,
+};
+
+/* possible OSC frequencies in Hz */
+static unsigned long tegra114_input_freq[] = {
+ [0] = 13000000,
+ [1] = 16800000,
+ [4] = 19200000,
+ [5] = 38400000,
+ [8] = 12000000,
+ [9] = 48000000,
+ [12] = 260000000,
+};
+
+#define MASK(x) (BIT(x) - 1)
+
+#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \
+ _clk_num, _regs, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \
+ periph_clk_enb_refcnt, _gate_flags, _clk_id, \
+ _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
+ _clk_num, _regs, _gate_flags, _clk_id, flags)\
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \
+ periph_clk_enb_refcnt, _gate_flags, _clk_id, \
+ _parents##_idx, flags)
+
+#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
+ _clk_num, _regs, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 29, MASK(3), 0, 0, 8, 1, 0, _regs, _clk_num, \
+ periph_clk_enb_refcnt, _gate_flags, _clk_id, \
+ _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
+ _clk_num, _regs, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
+ _clk_num, periph_clk_enb_refcnt, _gate_flags, \
+ _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
+ _clk_num, _regs, _gate_flags, _clk_id, flags)\
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
+ _clk_num, periph_clk_enb_refcnt, _gate_flags, \
+ _clk_id, _parents##_idx, flags)
+
+#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\
+ _clk_num, _regs, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
+ _clk_num, periph_clk_enb_refcnt, _gate_flags, \
+ _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
+ _clk_num, _regs, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs,\
+ _clk_num, periph_clk_enb_refcnt, 0, _clk_id, \
+ _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\
+ _clk_num, _regs, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ 30, MASK(2), 0, 0, 16, 0, 0, _regs, _clk_num, \
+ periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
+ _mux_shift, _mux_mask, _clk_num, _regs, \
+ _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+ _mux_shift, _mux_mask, 0, 0, 0, 0, 0, _regs, \
+ _clk_num, periph_clk_enb_refcnt, _gate_flags, \
+ _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \
+ _clk_num, _regs, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \
+ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \
+ _clk_num, periph_clk_enb_refcnt, _gate_flags, \
+ _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\
+ _regs, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \
+ _offset, 16, 0xE01F, 0, 0, 8, 1, 0, _regs, _clk_num, \
+ periph_clk_enb_refcnt, _gate_flags , _clk_id, \
+ mux_d_audio_clk_idx, 0)
+
+enum tegra114_clk {
+ rtc = 4, timer = 5, uarta = 6, sdmmc2 = 9, i2s1 = 11, i2c1 = 12,
+ ndflash = 13, sdmmc1 = 14, sdmmc4 = 15, pwm = 17, i2s2 = 18, epp = 19,
+ gr_2d = 21, usbd = 22, isp = 23, gr_3d = 24, disp2 = 26, disp1 = 27,
+ host1x = 28, vcp = 29, i2s0 = 30, apbdma = 34, kbc = 36, kfuse = 40,
+ sbc1 = 41, nor = 42, sbc2 = 44, sbc3 = 46, i2c5 = 47, dsia = 48,
+ mipi = 50, hdmi = 51, csi = 52, i2c2 = 54, uartc = 55, mipi_cal = 56,
+ emc, usb2, usb3, vde = 61, bsea = 62, bsev = 63, uartd = 65,
+ i2c3 = 67, sbc4 = 68, sdmmc3 = 69, owr = 71, csite = 73,
+ la = 76, trace = 77, soc_therm = 78, dtv = 79, ndspeed = 80,
+ i2cslow = 81, dsib = 82, tsec = 83, xusb_host = 89, msenc = 91,
+ csus = 92, mselect = 99, tsensor = 100, i2s3 = 101, i2s4 = 102,
+ i2c4 = 103, sbc5 = 104, sbc6 = 105, d_audio, apbif = 107, dam0, dam1,
+ dam2, hda2codec_2x = 111, audio0_2x = 113, audio1_2x, audio2_2x,
+ audio3_2x, audio4_2x, spdif_2x, actmon = 119, extern1 = 120,
+ extern2 = 121, extern3 = 122, hda = 125, se = 127, hda2hdmi = 128,
+ cilab = 144, cilcd = 145, cile = 146, dsialp = 147, dsiblp = 148,
+ dds = 150, dp2 = 152, amx = 153, adx = 154, xusb_ss = 156, uartb = 192,
+ vfir, spdif_in, spdif_out, vi, vi_sensor, fuse, fuse_burn, clk_32k,
+ clk_m, clk_m_div2, clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_c2,
+ pll_c3, pll_m, pll_m_out1, pll_p, pll_p_out1, pll_p_out2, pll_p_out3,
+ pll_p_out4, pll_a, pll_a_out0, pll_d, pll_d_out0, pll_d2, pll_d2_out0,
+ pll_u, pll_u_480M, pll_u_60M, pll_u_48M, pll_u_12M, pll_x, pll_x_out0,
+ pll_re_vco, pll_re_out, pll_e_out0, spdif_in_sync, i2s0_sync,
+ i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, vimclk_sync, audio0,
+ audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3,
+ blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src,
+ xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp,
+
+ /* Mux clocks */
+
+ audio0_mux = 300, audio1_mux, audio2_mux, audio3_mux, audio4_mux,
+ spdif_mux, clk_out_1_mux, clk_out_2_mux, clk_out_3_mux, dsia_mux,
+ dsib_mux, clk_max,
+};
+
+struct utmi_clk_param {
+ /* Oscillator Frequency in KHz */
+ u32 osc_frequency;
+ /* UTMIP PLL Enable Delay Count */
+ u8 enable_delay_count;
+ /* UTMIP PLL Stable count */
+ u8 stable_count;
+ /* UTMIP PLL Active delay count */
+ u8 active_delay_count;
+ /* UTMIP PLL Xtal frequency count */
+ u8 xtal_freq_count;
+};
+
+static const struct utmi_clk_param utmi_parameters[] = {
+ {.osc_frequency = 13000000, .enable_delay_count = 0x02,
+ .stable_count = 0x33, .active_delay_count = 0x05,
+ .xtal_freq_count = 0x7F},
+ {.osc_frequency = 19200000, .enable_delay_count = 0x03,
+ .stable_count = 0x4B, .active_delay_count = 0x06,
+ .xtal_freq_count = 0xBB},
+ {.osc_frequency = 12000000, .enable_delay_count = 0x02,
+ .stable_count = 0x2F, .active_delay_count = 0x04,
+ .xtal_freq_count = 0x76},
+ {.osc_frequency = 26000000, .enable_delay_count = 0x04,
+ .stable_count = 0x66, .active_delay_count = 0x09,
+ .xtal_freq_count = 0xFE},
+ {.osc_frequency = 16800000, .enable_delay_count = 0x03,
+ .stable_count = 0x41, .active_delay_count = 0x0A,
+ .xtal_freq_count = 0xA4},
+};
+
+/* peripheral mux definitions */
+
+#define MUX_I2S_SPDIF(_id) \
+static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \
+ #_id, "pll_p",\
+ "clk_m"};
+MUX_I2S_SPDIF(audio0)
+MUX_I2S_SPDIF(audio1)
+MUX_I2S_SPDIF(audio2)
+MUX_I2S_SPDIF(audio3)
+MUX_I2S_SPDIF(audio4)
+MUX_I2S_SPDIF(audio)
+
+#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL
+
+static const char *mux_pllp_pllc_pllm_clkm[] = {
+ "pll_p", "pll_c", "pll_m", "clk_m"
+};
+#define mux_pllp_pllc_pllm_clkm_idx NULL
+
+static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" };
+#define mux_pllp_pllc_pllm_idx NULL
+
+static const char *mux_pllp_pllc_clk32_clkm[] = {
+ "pll_p", "pll_c", "clk_32k", "clk_m"
+};
+#define mux_pllp_pllc_clk32_clkm_idx NULL
+
+static const char *mux_plla_pllc_pllp_clkm[] = {
+ "pll_a_out0", "pll_c", "pll_p", "clk_m"
+};
+#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx
+
+static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = {
+ "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m"
+};
+static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = {
+ [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
+};
+
+static const char *mux_pllp_clkm[] = {
+ "pll_p", "clk_m"
+};
+static u32 mux_pllp_clkm_idx[] = {
+ [0] = 0, [1] = 3,
+};
+
+static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = {
+ "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0"
+};
+#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx
+
+static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
+ "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c",
+ "pll_d2_out0", "clk_m"
+};
+#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL
+
+static const char *mux_pllm_pllc_pllp_plla[] = {
+ "pll_m", "pll_c", "pll_p", "pll_a_out0"
+};
+#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx
+
+static const char *mux_pllp_pllc_clkm[] = {
+ "pll_p", "pll_c", "pll_m"
+};
+static u32 mux_pllp_pllc_clkm_idx[] = {
+ [0] = 0, [1] = 1, [2] = 3,
+};
+
+static const char *mux_pllp_pllc_clkm_clk32[] = {
+ "pll_p", "pll_c", "clk_m", "clk_32k"
+};
+#define mux_pllp_pllc_clkm_clk32_idx NULL
+
+static const char *mux_plla_clk32_pllp_clkm_plle[] = {
+ "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0"
+};
+#define mux_plla_clk32_pllp_clkm_plle_idx NULL
+
+static const char *mux_clkm_pllp_pllc_pllre[] = {
+ "clk_m", "pll_p", "pll_c", "pll_re_out"
+};
+static u32 mux_clkm_pllp_pllc_pllre_idx[] = {
+ [0] = 0, [1] = 1, [2] = 3, [3] = 5,
+};
+
+static const char *mux_clkm_48M_pllp_480M[] = {
+ "clk_m", "pll_u_48M", "pll_p", "pll_u_480M"
+};
+#define mux_clkm_48M_pllp_480M_idx NULL
+
+static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = {
+ "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref"
+};
+static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = {
+ [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7,
+};
+
+static const char *mux_plld_out0_plld2_out0[] = {
+ "pll_d_out0", "pll_d2_out0",
+};
+#define mux_plld_out0_plld2_out0_idx NULL
+
+static const char *mux_d_audio_clk[] = {
+ "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync",
+ "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",
+};
+static u32 mux_d_audio_clk_idx[] = {
+ [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001,
+ [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007,
+};
+
+static const char *mux_pllmcp_clkm[] = {
+ "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud",
+};
+
+static const struct clk_div_table pll_re_div_table[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },
+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 5 },
+ { .val = 5, .div = 6 },
+ { .val = 0, .div = 0 },
+};
+
+static struct clk *clks[clk_max];
+static struct clk_onecell_data clk_data;
+
+static unsigned long osc_freq;
+static unsigned long pll_ref_freq;
+
+static int __init tegra114_osc_clk_init(void __iomem *clk_base)
+{
+ struct clk *clk;
+ u32 val, pll_ref_div;
+
+ val = readl_relaxed(clk_base + OSC_CTRL);
+
+ osc_freq = tegra114_input_freq[val >> OSC_CTRL_OSC_FREQ_SHIFT];
+ if (!osc_freq) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ /* clk_m */
+ clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT,
+ osc_freq);
+ clk_register_clkdev(clk, "clk_m", NULL);
+ clks[clk_m] = clk;
+
+ /* pll_ref */
+ val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3;
+ pll_ref_div = 1 << val;
+ clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
+ CLK_SET_RATE_PARENT, 1, pll_ref_div);
+ clk_register_clkdev(clk, "pll_ref", NULL);
+ clks[pll_ref] = clk;
+
+ pll_ref_freq = osc_freq / pll_ref_div;
+
+ return 0;
+}
+
+static void __init tegra114_fixed_clk_init(void __iomem *clk_base)
+{
+ struct clk *clk;
+
+ /* clk_32k */
+ clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT,
+ 32768);
+ clk_register_clkdev(clk, "clk_32k", NULL);
+ clks[clk_32k] = clk;
+
+ /* clk_m_div2 */
+ clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m",
+ CLK_SET_RATE_PARENT, 1, 2);
+ clk_register_clkdev(clk, "clk_m_div2", NULL);
+ clks[clk_m_div2] = clk;
+
+ /* clk_m_div4 */
+ clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m",
+ CLK_SET_RATE_PARENT, 1, 4);
+ clk_register_clkdev(clk, "clk_m_div4", NULL);
+ clks[clk_m_div4] = clk;
+
+}
+
+static __init void tegra114_utmi_param_configure(void __iomem *clk_base)
+{
+ u32 reg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
+ if (osc_freq == utmi_parameters[i].osc_frequency)
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(utmi_parameters)) {
+ pr_err("%s: Unexpected oscillator freq %lu\n", __func__,
+ osc_freq);
+ return;
+ }
+
+ reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2);
+
+ /* Program UTMIP PLL stable and active counts */
+ /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
+ reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
+ reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count);
+
+ reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
+
+ reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].
+ active_delay_count);
+
+ /* Remove power downs from UTMIP PLL control bits */
+ reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
+ reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
+ reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
+
+ writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2);
+
+ /* Program UTMIP PLL delay and oscillator frequency counts */
+ reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
+ reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
+
+ reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].
+ enable_delay_count);
+
+ reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
+ reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i].
+ xtal_freq_count);
+
+ /* Remove power downs from UTMIP PLL control bits */
+ reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+ reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
+ reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP;
+ reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
+ writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
+
+ /* Setup HW control of UTMIPLL */
+ reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+ reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET;
+ reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL;
+ reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE;
+ writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+
+ reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
+ reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP;
+ reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+ writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
+
+ udelay(1);
+
+ /* Setup SW override of UTMIPLL assuming USB2.0
+ ports are assigned to USB2 */
+ reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+ reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL;
+ reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
+ writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+
+ udelay(1);
+
+ /* Enable HW control UTMIPLL */
+ reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+ reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE;
+ writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+}
+
+static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params)
+{
+ pll_params->vco_min =
+ DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq;
+}
+
+static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params,
+ void __iomem *clk_base)
+{
+ u32 val;
+ u32 step_a, step_b;
+
+ switch (pll_ref_freq) {
+ case 12000000:
+ case 13000000:
+ case 26000000:
+ step_a = 0x2B;
+ step_b = 0x0B;
+ break;
+ case 16800000:
+ step_a = 0x1A;
+ step_b = 0x09;
+ break;
+ case 19200000:
+ step_a = 0x12;
+ step_b = 0x08;
+ break;
+ default:
+ pr_err("%s: Unexpected reference rate %lu\n",
+ __func__, pll_ref_freq);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ val = step_a << pll_params->stepa_shift;
+ val |= step_b << pll_params->stepb_shift;
+ writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg);
+
+ return 0;
+}
+
+static void __init _init_iddq(struct tegra_clk_pll_params *pll_params,
+ void __iomem *clk_base)
+{
+ u32 val, val_iddq;
+
+ val = readl_relaxed(clk_base + pll_params->base_reg);
+ val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg);
+
+ if (val & BIT(30))
+ WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx));
+ else {
+ val_iddq |= BIT(pll_params->iddq_bit_idx);
+ writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg);
+ }
+}
+
+static void __init tegra114_pll_init(void __iomem *clk_base,
+ void __iomem *pmc)
+{
+ u32 val;
+ struct clk *clk;
+
+ /* PLLC */
+ _clip_vco_min(&pll_c_params);
+ if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) {
+ _init_iddq(&pll_c_params, clk_base);
+ clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
+ pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK,
+ pll_c_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_c", NULL);
+ clks[pll_c] = clk;
+
+ /* PLLC_OUT1 */
+ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
+ clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
+ 8, 8, 1, NULL);
+ clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
+ clk_base + PLLC_OUT, 1, 0,
+ CLK_SET_RATE_PARENT, 0, NULL);
+ clk_register_clkdev(clk, "pll_c_out1", NULL);
+ clks[pll_c_out1] = clk;
+ }
+
+ /* PLLC2 */
+ _clip_vco_min(&pll_c2_params);
+ clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0,
+ &pll_c2_params, TEGRA_PLL_USE_LOCK,
+ pll_cx_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_c2", NULL);
+ clks[pll_c2] = clk;
+
+ /* PLLC3 */
+ _clip_vco_min(&pll_c3_params);
+ clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0,
+ &pll_c3_params, TEGRA_PLL_USE_LOCK,
+ pll_cx_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_c3", NULL);
+ clks[pll_c3] = clk;
+
+ /* PLLP */
+ clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0,
+ 408000000, &pll_p_params,
+ TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK,
+ pll_p_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_p", NULL);
+ clks[pll_p] = clk;
+
+ /* PLLP_OUT1 */
+ clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p",
+ clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
+ TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock);
+ clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div",
+ clk_base + PLLP_OUTA, 1, 0,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+ &pll_div_lock);
+ clk_register_clkdev(clk, "pll_p_out1", NULL);
+ clks[pll_p_out1] = clk;
+
+ /* PLLP_OUT2 */
+ clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p",
+ clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
+ TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
+ &pll_div_lock);
+ clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div",
+ clk_base + PLLP_OUTA, 17, 16,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+ &pll_div_lock);
+ clk_register_clkdev(clk, "pll_p_out2", NULL);
+ clks[pll_p_out2] = clk;
+
+ /* PLLP_OUT3 */
+ clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p",
+ clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED |
+ TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock);
+ clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div",
+ clk_base + PLLP_OUTB, 1, 0,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+ &pll_div_lock);
+ clk_register_clkdev(clk, "pll_p_out3", NULL);
+ clks[pll_p_out3] = clk;
+
+ /* PLLP_OUT4 */
+ clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p",
+ clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED |
+ TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
+ &pll_div_lock);
+ clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div",
+ clk_base + PLLP_OUTB, 17, 16,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+ &pll_div_lock);
+ clk_register_clkdev(clk, "pll_p_out4", NULL);
+ clks[pll_p_out4] = clk;
+
+ /* PLLM */
+ _clip_vco_min(&pll_m_params);
+ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0,
+ &pll_m_params, TEGRA_PLL_USE_LOCK,
+ pll_m_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_m", NULL);
+ clks[pll_m] = clk;
+
+ /* PLLM_OUT1 */
+ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
+ clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
+ 8, 8, 1, NULL);
+ clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
+ clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED |
+ CLK_SET_RATE_PARENT, 0, NULL);
+ clk_register_clkdev(clk, "pll_m_out1", NULL);
+ clks[pll_m_out1] = clk;
+
+ /* PLLM_UD */
+ clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m",
+ CLK_SET_RATE_PARENT, 1, 1);
+
+ /* PLLX */
+ _clip_vco_min(&pll_x_params);
+ if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) {
+ _init_iddq(&pll_x_params, clk_base);
+ clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
+ pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params,
+ TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_x", NULL);
+ clks[pll_x] = clk;
+ }
+
+ /* PLLX_OUT0 */
+ clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x",
+ CLK_SET_RATE_PARENT, 1, 2);
+ clk_register_clkdev(clk, "pll_x_out0", NULL);
+ clks[pll_x_out0] = clk;
+
+ /* PLLU */
+ val = readl(clk_base + pll_u_params.base_reg);
+ val &= ~BIT(24); /* disable PLLU_OVERRIDE */
+ writel(val, clk_base + pll_u_params.base_reg);
+
+ clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0,
+ 0, &pll_u_params, TEGRA_PLLU |
+ TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
+ TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock);
+ clk_register_clkdev(clk, "pll_u", NULL);
+ clks[pll_u] = clk;
+
+ tegra114_utmi_param_configure(clk_base);
+
+ /* PLLU_480M */
+ clk = clk_register_gate(NULL, "pll_u_480M", "pll_u",
+ CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
+ 22, 0, &pll_u_lock);
+ clk_register_clkdev(clk, "pll_u_480M", NULL);
+ clks[pll_u_480M] = clk;
+
+ /* PLLU_60M */
+ clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u",
+ CLK_SET_RATE_PARENT, 1, 8);
+ clk_register_clkdev(clk, "pll_u_60M", NULL);
+ clks[pll_u_60M] = clk;
+
+ /* PLLU_48M */
+ clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u",
+ CLK_SET_RATE_PARENT, 1, 10);
+ clk_register_clkdev(clk, "pll_u_48M", NULL);
+ clks[pll_u_48M] = clk;
+
+ /* PLLU_12M */
+ clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u",
+ CLK_SET_RATE_PARENT, 1, 40);
+ clk_register_clkdev(clk, "pll_u_12M", NULL);
+ clks[pll_u_12M] = clk;
+
+ /* PLLD */
+ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
+ 0, &pll_d_params,
+ TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
+ TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock);
+ clk_register_clkdev(clk, "pll_d", NULL);
+ clks[pll_d] = clk;
+
+ /* PLLD_OUT0 */
+ clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d",
+ CLK_SET_RATE_PARENT, 1, 2);
+ clk_register_clkdev(clk, "pll_d_out0", NULL);
+ clks[pll_d_out0] = clk;
+
+ /* PLLD2 */
+ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0,
+ 0, &pll_d2_params,
+ TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
+ TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock);
+ clk_register_clkdev(clk, "pll_d2", NULL);
+ clks[pll_d2] = clk;
+
+ /* PLLD2_OUT0 */
+ clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2",
+ CLK_SET_RATE_PARENT, 1, 2);
+ clk_register_clkdev(clk, "pll_d2_out0", NULL);
+ clks[pll_d2_out0] = clk;
+
+ /* PLLA */
+ clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0,
+ 0, &pll_a_params, TEGRA_PLL_HAS_CPCON |
+ TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_a", NULL);
+ clks[pll_a] = clk;
+
+ /* PLLA_OUT0 */
+ clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a",
+ clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
+ 8, 8, 1, NULL);
+ clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div",
+ clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED |
+ CLK_SET_RATE_PARENT, 0, NULL);
+ clk_register_clkdev(clk, "pll_a_out0", NULL);
+ clks[pll_a_out0] = clk;
+
+ /* PLLRE */
+ _clip_vco_min(&pll_re_vco_params);
+ clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
+ 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK,
+ NULL, &pll_re_lock, pll_ref_freq);
+ clk_register_clkdev(clk, "pll_re_vco", NULL);
+ clks[pll_re_vco] = clk;
+
+ clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0,
+ clk_base + PLLRE_BASE, 16, 4, 0,
+ pll_re_div_table, &pll_re_lock);
+ clk_register_clkdev(clk, "pll_re_out", NULL);
+ clks[pll_re_out] = clk;
+
+ /* PLLE */
+ clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco",
+ clk_base, 0, 100000000, &pll_e_params,
+ pll_e_freq_table, NULL);
+ clk_register_clkdev(clk, "pll_e_out0", NULL);
+ clks[pll_e_out0] = clk;
+}
+
+static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync",
+ "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",
+};
+
+static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
+ "clk_m_div4", "extern1",
+};
+
+static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
+ "clk_m_div4", "extern2",
+};
+
+static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
+ "clk_m_div4", "extern3",
+};
+
+static void __init tegra114_audio_clk_init(void __iomem *clk_base)
+{
+ struct clk *clk;
+
+ /* spdif_in_sync */
+ clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000,
+ 24000000);
+ clk_register_clkdev(clk, "spdif_in_sync", NULL);
+ clks[spdif_in_sync] = clk;
+
+ /* i2s0_sync */
+ clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000);
+ clk_register_clkdev(clk, "i2s0_sync", NULL);
+ clks[i2s0_sync] = clk;
+
+ /* i2s1_sync */
+ clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000);
+ clk_register_clkdev(clk, "i2s1_sync", NULL);
+ clks[i2s1_sync] = clk;
+
+ /* i2s2_sync */
+ clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000);
+ clk_register_clkdev(clk, "i2s2_sync", NULL);
+ clks[i2s2_sync] = clk;
+
+ /* i2s3_sync */
+ clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000);
+ clk_register_clkdev(clk, "i2s3_sync", NULL);
+ clks[i2s3_sync] = clk;
+
+ /* i2s4_sync */
+ clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000);
+ clk_register_clkdev(clk, "i2s4_sync", NULL);
+ clks[i2s4_sync] = clk;
+
+ /* vimclk_sync */
+ clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000);
+ clk_register_clkdev(clk, "vimclk_sync", NULL);
+ clks[vimclk_sync] = clk;
+
+ /* audio0 */
+ clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk,
+ ARRAY_SIZE(mux_audio_sync_clk), 0,
+ clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0,
+ NULL);
+ clks[audio0_mux] = clk;
+ clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0,
+ clk_base + AUDIO_SYNC_CLK_I2S0, 4,
+ CLK_GATE_SET_TO_DISABLE, NULL);
+ clk_register_clkdev(clk, "audio0", NULL);
+ clks[audio0] = clk;
+
+ /* audio1 */
+ clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk,
+ ARRAY_SIZE(mux_audio_sync_clk), 0,
+ clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0,
+ NULL);
+ clks[audio1_mux] = clk;
+ clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0,
+ clk_base + AUDIO_SYNC_CLK_I2S1, 4,
+ CLK_GATE_SET_TO_DISABLE, NULL);
+ clk_register_clkdev(clk, "audio1", NULL);
+ clks[audio1] = clk;
+
+ /* audio2 */
+ clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk,
+ ARRAY_SIZE(mux_audio_sync_clk), 0,
+ clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0,
+ NULL);
+ clks[audio2_mux] = clk;
+ clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0,
+ clk_base + AUDIO_SYNC_CLK_I2S2, 4,
+ CLK_GATE_SET_TO_DISABLE, NULL);
+ clk_register_clkdev(clk, "audio2", NULL);
+ clks[audio2] = clk;
+
+ /* audio3 */
+ clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk,
+ ARRAY_SIZE(mux_audio_sync_clk), 0,
+ clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0,
+ NULL);
+ clks[audio3_mux] = clk;
+ clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0,
+ clk_base + AUDIO_SYNC_CLK_I2S3, 4,
+ CLK_GATE_SET_TO_DISABLE, NULL);
+ clk_register_clkdev(clk, "audio3", NULL);
+ clks[audio3] = clk;
+
+ /* audio4 */
+ clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk,
+ ARRAY_SIZE(mux_audio_sync_clk), 0,
+ clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0,
+ NULL);
+ clks[audio4_mux] = clk;
+ clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0,
+ clk_base + AUDIO_SYNC_CLK_I2S4, 4,
+ CLK_GATE_SET_TO_DISABLE, NULL);
+ clk_register_clkdev(clk, "audio4", NULL);
+ clks[audio4] = clk;
+
+ /* spdif */
+ clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk,
+ ARRAY_SIZE(mux_audio_sync_clk), 0,
+ clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0,
+ NULL);
+ clks[spdif_mux] = clk;
+ clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0,
+ clk_base + AUDIO_SYNC_CLK_SPDIF, 4,
+ CLK_GATE_SET_TO_DISABLE, NULL);
+ clk_register_clkdev(clk, "spdif", NULL);
+ clks[spdif] = clk;
+
+ /* audio0_2x */
+ clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0",
+ CLK_SET_RATE_PARENT, 2, 1);
+ clk = tegra_clk_register_divider("audio0_div", "audio0_doubler",
+ clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1,
+ 0, &clk_doubler_lock);
+ clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div",
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ CLK_SET_RATE_PARENT, 113, &periph_v_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, "audio0_2x", NULL);
+ clks[audio0_2x] = clk;
+
+ /* audio1_2x */
+ clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1",
+ CLK_SET_RATE_PARENT, 2, 1);
+ clk = tegra_clk_register_divider("audio1_div", "audio1_doubler",
+ clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1,
+ 0, &clk_doubler_lock);
+ clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div",
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ CLK_SET_RATE_PARENT, 114, &periph_v_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, "audio1_2x", NULL);
+ clks[audio1_2x] = clk;
+
+ /* audio2_2x */
+ clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2",
+ CLK_SET_RATE_PARENT, 2, 1);
+ clk = tegra_clk_register_divider("audio2_div", "audio2_doubler",
+ clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1,
+ 0, &clk_doubler_lock);
+ clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div",
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ CLK_SET_RATE_PARENT, 115, &periph_v_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, "audio2_2x", NULL);
+ clks[audio2_2x] = clk;
+
+ /* audio3_2x */
+ clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3",
+ CLK_SET_RATE_PARENT, 2, 1);
+ clk = tegra_clk_register_divider("audio3_div", "audio3_doubler",
+ clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1,
+ 0, &clk_doubler_lock);
+ clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div",
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ CLK_SET_RATE_PARENT, 116, &periph_v_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, "audio3_2x", NULL);
+ clks[audio3_2x] = clk;
+
+ /* audio4_2x */
+ clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4",
+ CLK_SET_RATE_PARENT, 2, 1);
+ clk = tegra_clk_register_divider("audio4_div", "audio4_doubler",
+ clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1,
+ 0, &clk_doubler_lock);
+ clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div",
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ CLK_SET_RATE_PARENT, 117, &periph_v_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, "audio4_2x", NULL);
+ clks[audio4_2x] = clk;
+
+ /* spdif_2x */
+ clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif",
+ CLK_SET_RATE_PARENT, 2, 1);
+ clk = tegra_clk_register_divider("spdif_div", "spdif_doubler",
+ clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1,
+ 0, &clk_doubler_lock);
+ clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div",
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ CLK_SET_RATE_PARENT, 118,
+ &periph_v_regs, periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, "spdif_2x", NULL);
+ clks[spdif_2x] = clk;
+}
+
+static void __init tegra114_pmc_clk_init(void __iomem *pmc_base)
+{
+ struct clk *clk;
+
+ /* clk_out_1 */
+ clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents,
+ ARRAY_SIZE(clk_out1_parents), 0,
+ pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0,
+ &clk_out_lock);
+ clks[clk_out_1_mux] = clk;
+ clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0,
+ pmc_base + PMC_CLK_OUT_CNTRL, 2, 0,
+ &clk_out_lock);
+ clk_register_clkdev(clk, "extern1", "clk_out_1");
+ clks[clk_out_1] = clk;
+
+ /* clk_out_2 */
+ clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
+ ARRAY_SIZE(clk_out1_parents), 0,
+ pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
+ &clk_out_lock);
+ clks[clk_out_2_mux] = clk;
+ clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0,
+ pmc_base + PMC_CLK_OUT_CNTRL, 10, 0,
+ &clk_out_lock);
+ clk_register_clkdev(clk, "extern2", "clk_out_2");
+ clks[clk_out_2] = clk;
+
+ /* clk_out_3 */
+ clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
+ ARRAY_SIZE(clk_out1_parents), 0,
+ pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
+ &clk_out_lock);
+ clks[clk_out_3_mux] = clk;
+ clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0,
+ pmc_base + PMC_CLK_OUT_CNTRL, 18, 0,
+ &clk_out_lock);
+ clk_register_clkdev(clk, "extern3", "clk_out_3");
+ clks[clk_out_3] = clk;
+
+ /* blink */
+ clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0,
+ pmc_base + PMC_DPD_PADS_ORIDE,
+ PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL);
+ clk = clk_register_gate(NULL, "blink", "blink_override", 0,
+ pmc_base + PMC_CTRL,
+ PMC_CTRL_BLINK_ENB, 0, NULL);
+ clk_register_clkdev(clk, "blink", NULL);
+ clks[blink] = clk;
+
+}
+
+static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
+ "pll_p_out3", "pll_p_out2", "unused",
+ "clk_32k", "pll_m_out1" };
+
+static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
+ "pll_p", "pll_p_out4", "unused",
+ "unused", "pll_x" };
+
+static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
+ "pll_p", "pll_p_out4", "unused",
+ "unused", "pll_x", "pll_x_out0" };
+
+static void __init tegra114_super_clk_init(void __iomem *clk_base)
+{
+ struct clk *clk;
+
+ /* CCLKG */
+ clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
+ ARRAY_SIZE(cclk_g_parents),
+ CLK_SET_RATE_PARENT,
+ clk_base + CCLKG_BURST_POLICY,
+ 0, 4, 0, 0, NULL);
+ clk_register_clkdev(clk, "cclk_g", NULL);
+ clks[cclk_g] = clk;
+
+ /* CCLKLP */
+ clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents,
+ ARRAY_SIZE(cclk_lp_parents),
+ CLK_SET_RATE_PARENT,
+ clk_base + CCLKLP_BURST_POLICY,
+ 0, 4, 8, 9, NULL);
+ clk_register_clkdev(clk, "cclk_lp", NULL);
+ clks[cclk_lp] = clk;
+
+ /* SCLK */
+ clk = tegra_clk_register_super_mux("sclk", sclk_parents,
+ ARRAY_SIZE(sclk_parents),
+ CLK_SET_RATE_PARENT,
+ clk_base + SCLK_BURST_POLICY,
+ 0, 4, 0, 0, NULL);
+ clk_register_clkdev(clk, "sclk", NULL);
+ clks[sclk] = clk;
+
+ /* HCLK */
+ clk = clk_register_divider(NULL, "hclk_div", "sclk", 0,
+ clk_base + SYSTEM_CLK_RATE, 4, 2, 0,
+ &sysrate_lock);
+ clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT |
+ CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE,
+ 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
+ clk_register_clkdev(clk, "hclk", NULL);
+ clks[hclk] = clk;
+
+ /* PCLK */
+ clk = clk_register_divider(NULL, "pclk_div", "hclk", 0,
+ clk_base + SYSTEM_CLK_RATE, 0, 2, 0,
+ &sysrate_lock);
+ clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT |
+ CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE,
+ 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
+ clk_register_clkdev(clk, "pclk", NULL);
+ clks[pclk] = clk;
+}
+
+static struct tegra_periph_init_data tegra_periph_clk_list[] = {
+ TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0),
+ TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1),
+ TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2),
+ TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3),
+ TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4),
+ TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out),
+ TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in),
+ TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, pwm),
+ TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, adx),
+ TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, amx),
+ TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda),
+ TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda2codec_2x),
+ TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1),
+ TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2),
+ TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3),
+ TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4),
+ TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5),
+ TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6),
+ TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed),
+ TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed),
+ TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir),
+ TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1),
+ TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2),
+ TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3),
+ TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4),
+ TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde),
+ TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite, CLK_IGNORE_UNUSED),
+ TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la),
+ TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, trace),
+ TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr),
+ TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor),
+ TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi),
+ TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, i2c1),
+ TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, i2c2),
+ TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, i2c3),
+ TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, i2c4),
+ TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, i2c5),
+ TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta),
+ TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb),
+ TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc),
+ TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd),
+ TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, gr_3d),
+ TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr_2d),
+ TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor),
+ TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi),
+ TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp),
+ TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_h_regs, TEGRA_PERIPH_WAR_1005168, msenc),
+ TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec),
+ TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x),
+ TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi),
+ TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, cilab),
+ TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, cilcd),
+ TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, cile),
+ TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, dsialp),
+ TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, dsiblp),
+ TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor),
+ TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon),
+ TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1),
+ TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2),
+ TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3),
+ TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow),
+ TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se),
+ TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED),
+ TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm),
+ TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src),
+ TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src),
+ TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_fs_src),
+ TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_ss_src),
+ TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_dev_src),
+ TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, d_audio),
+ TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam0),
+ TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam1),
+ TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam2),
+};
+
+static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
+ TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, disp1),
+ TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, disp2),
+};
+
+static __init void tegra114_periph_clk_init(void __iomem *clk_base)
+{
+ struct tegra_periph_init_data *data;
+ struct clk *clk;
+ int i;
+ u32 val;
+
+ /* apbdma */
+ clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base,
+ 0, 34, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[apbdma] = clk;
+
+ /* rtc */
+ clk = tegra_clk_register_periph_gate("rtc", "clk_32k",
+ TEGRA_PERIPH_ON_APB |
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ 0, 4, &periph_l_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, NULL, "rtc-tegra");
+ clks[rtc] = clk;
+
+ /* kbc */
+ clk = tegra_clk_register_periph_gate("kbc", "clk_32k",
+ TEGRA_PERIPH_ON_APB |
+ TEGRA_PERIPH_NO_RESET, clk_base,
+ 0, 36, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[kbc] = clk;
+
+ /* timer */
+ clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base,
+ 0, 5, &periph_l_regs,
+ periph_clk_enb_refcnt);
+ clk_register_clkdev(clk, NULL, "timer");
+ clks[timer] = clk;
+
+ /* kfuse */
+ clk = tegra_clk_register_periph_gate("kfuse", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 40,
+ &periph_h_regs, periph_clk_enb_refcnt);
+ clks[kfuse] = clk;
+
+ /* fuse */
+ clk = tegra_clk_register_periph_gate("fuse", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 39,
+ &periph_h_regs, periph_clk_enb_refcnt);
+ clks[fuse] = clk;
+
+ /* fuse_burn */
+ clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 39,
+ &periph_h_regs, periph_clk_enb_refcnt);
+ clks[fuse_burn] = clk;
+
+ /* apbif */
+ clk = tegra_clk_register_periph_gate("apbif", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 107,
+ &periph_v_regs, periph_clk_enb_refcnt);
+ clks[apbif] = clk;
+
+ /* hda2hdmi */
+ clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 128,
+ &periph_w_regs, periph_clk_enb_refcnt);
+ clks[hda2hdmi] = clk;
+
+ /* vcp */
+ clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0,
+ 29, &periph_l_regs,
+ periph_clk_enb_refcnt);
+ clks[vcp] = clk;
+
+ /* bsea */
+ clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base,
+ 0, 62, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[bsea] = clk;
+
+ /* bsev */
+ clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base,
+ 0, 63, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[bsev] = clk;
+
+ /* mipi-cal */
+ clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base,
+ 0, 56, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[mipi_cal] = clk;
+
+ /* usbd */
+ clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base,
+ 0, 22, &periph_l_regs,
+ periph_clk_enb_refcnt);
+ clks[usbd] = clk;
+
+ /* usb2 */
+ clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base,
+ 0, 58, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[usb2] = clk;
+
+ /* usb3 */
+ clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base,
+ 0, 59, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[usb3] = clk;
+
+ /* csi */
+ clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base,
+ 0, 52, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[csi] = clk;
+
+ /* isp */
+ clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0,
+ 23, &periph_l_regs,
+ periph_clk_enb_refcnt);
+ clks[isp] = clk;
+
+ /* csus */
+ clk = tegra_clk_register_periph_gate("csus", "clk_m",
+ TEGRA_PERIPH_NO_RESET, clk_base, 0, 92,
+ &periph_u_regs, periph_clk_enb_refcnt);
+ clks[csus] = clk;
+
+ /* dds */
+ clk = tegra_clk_register_periph_gate("dds", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 150,
+ &periph_w_regs, periph_clk_enb_refcnt);
+ clks[dds] = clk;
+
+ /* dp2 */
+ clk = tegra_clk_register_periph_gate("dp2", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 152,
+ &periph_w_regs, periph_clk_enb_refcnt);
+ clks[dp2] = clk;
+
+ /* dtv */
+ clk = tegra_clk_register_periph_gate("dtv", "clk_m",
+ TEGRA_PERIPH_ON_APB, clk_base, 0, 79,
+ &periph_u_regs, periph_clk_enb_refcnt);
+ clks[dtv] = clk;
+
+ /* dsia */
+ clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,
+ ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
+ clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock);
+ clks[dsia_mux] = clk;
+ clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base,
+ 0, 48, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[dsia] = clk;
+
+ /* dsib */
+ clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0,
+ ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
+ clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock);
+ clks[dsib_mux] = clk;
+ clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base,
+ 0, 82, &periph_u_regs,
+ periph_clk_enb_refcnt);
+ clks[dsib] = clk;
+
+ /* xusb_hs_src */
+ val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC);
+ val |= BIT(25); /* always select PLLU_60M */
+ writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC);
+
+ clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0,
+ 1, 1);
+ clks[xusb_hs_src] = clk;
+
+ /* xusb_host */
+ clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0,
+ clk_base, 0, 89, &periph_u_regs,
+ periph_clk_enb_refcnt);
+ clks[xusb_host] = clk;
+
+ /* xusb_ss */
+ clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0,
+ clk_base, 0, 156, &periph_w_regs,
+ periph_clk_enb_refcnt);
+ clks[xusb_host] = clk;
+
+ /* xusb_dev */
+ clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0,
+ clk_base, 0, 95, &periph_u_regs,
+ periph_clk_enb_refcnt);
+ clks[xusb_dev] = clk;
+
+ /* emc */
+ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
+ ARRAY_SIZE(mux_pllmcp_clkm), 0,
+ clk_base + CLK_SOURCE_EMC,
+ 29, 3, 0, NULL);
+ clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base,
+ CLK_IGNORE_UNUSED, 57, &periph_h_regs,
+ periph_clk_enb_refcnt);
+ clks[emc] = clk;
+
+ for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
+ data = &tegra_periph_clk_list[i];
+ clk = tegra_clk_register_periph(data->name, data->parent_names,
+ data->num_parents, &data->periph,
+ clk_base, data->offset, data->flags);
+ clks[data->clk_id] = clk;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) {
+ data = &tegra_periph_nodiv_clk_list[i];
+ clk = tegra_clk_register_periph_nodiv(data->name,
+ data->parent_names, data->num_parents,
+ &data->periph, clk_base, data->offset);
+ clks[data->clk_id] = clk;
+ }
+}
+
+static struct tegra_cpu_car_ops tegra114_cpu_car_ops;
+
+static const struct of_device_id pmc_match[] __initconst = {
+ { .compatible = "nvidia,tegra114-pmc" },
+ {},
+};
+
+static __initdata struct tegra_clk_init_table init_table[] = {
+ {uarta, pll_p, 408000000, 0},
+ {uartb, pll_p, 408000000, 0},
+ {uartc, pll_p, 408000000, 0},
+ {uartd, pll_p, 408000000, 0},
+ {pll_a, clk_max, 564480000, 1},
+ {pll_a_out0, clk_max, 11289600, 1},
+ {extern1, pll_a_out0, 0, 1},
+ {clk_out_1_mux, extern1, 0, 1},
+ {clk_out_1, clk_max, 0, 1},
+ {i2s0, pll_a_out0, 11289600, 0},
+ {i2s1, pll_a_out0, 11289600, 0},
+ {i2s2, pll_a_out0, 11289600, 0},
+ {i2s3, pll_a_out0, 11289600, 0},
+ {i2s4, pll_a_out0, 11289600, 0},
+ {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */
+};
+
+static void __init tegra114_clock_apply_init_table(void)
+{
+ tegra_init_from_table(init_table, clks, clk_max);
+}
+
+void __init tegra114_clock_init(struct device_node *np)
+{
+ struct device_node *node;
+ int i;
+
+ clk_base = of_iomap(np, 0);
+ if (!clk_base) {
+ pr_err("ioremap tegra114 CAR failed\n");
+ return;
+ }
+
+ node = of_find_matching_node(NULL, pmc_match);
+ if (!node) {
+ pr_err("Failed to find pmc node\n");
+ WARN_ON(1);
+ return;
+ }
+
+ pmc_base = of_iomap(node, 0);
+ if (!pmc_base) {
+ pr_err("Can't map pmc registers\n");
+ WARN_ON(1);
+ return;
+ }
+
+ if (tegra114_osc_clk_init(clk_base) < 0)
+ return;
+
+ tegra114_fixed_clk_init(clk_base);
+ tegra114_pll_init(clk_base, pmc_base);
+ tegra114_periph_clk_init(clk_base);
+ tegra114_audio_clk_init(clk_base);
+ tegra114_pmc_clk_init(pmc_base);
+ tegra114_super_clk_init(clk_base);
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ if (IS_ERR(clks[i])) {
+ pr_err
+ ("Tegra114 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+ }
+ if (!clks[i])
+ clks[i] = ERR_PTR(-EINVAL);
+ }
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+ tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
+
+ tegra_cpu_car_ops = &tegra114_cpu_car_ops;
+}
#define PLLE_BASE 0xe8
#define PLLE_MISC 0xec
-#define PLL_BASE_LOCK 27
-#define PLLE_MISC_LOCK 11
+#define PLL_BASE_LOCK BIT(27)
+#define PLLE_MISC_LOCK BIT(11)
#define PLL_MISC_LOCK_ENABLE 18
#define PLLDU_MISC_LOCK_ENABLE 22
dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2,
usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb,
- iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev1, cdev2,
+ iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev2, cdev1,
uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve,
osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0,
pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1,
static struct clk_onecell_data clk_data;
static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
- { 12000000, 600000000, 600, 12, 1, 8 },
- { 13000000, 600000000, 600, 13, 1, 8 },
- { 19200000, 600000000, 500, 16, 1, 6 },
- { 26000000, 600000000, 600, 26, 1, 8 },
+ { 12000000, 600000000, 600, 12, 0, 8 },
+ { 13000000, 600000000, 600, 13, 0, 8 },
+ { 19200000, 600000000, 500, 16, 0, 6 },
+ { 26000000, 600000000, 600, 26, 0, 8 },
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
- { 12000000, 666000000, 666, 12, 1, 8},
- { 13000000, 666000000, 666, 13, 1, 8},
- { 19200000, 666000000, 555, 16, 1, 8},
- { 26000000, 666000000, 666, 26, 1, 8},
- { 12000000, 600000000, 600, 12, 1, 8},
- { 13000000, 600000000, 600, 13, 1, 8},
- { 19200000, 600000000, 375, 12, 1, 6},
- { 26000000, 600000000, 600, 26, 1, 8},
+ { 12000000, 666000000, 666, 12, 0, 8},
+ { 13000000, 666000000, 666, 13, 0, 8},
+ { 19200000, 666000000, 555, 16, 0, 8},
+ { 26000000, 666000000, 666, 26, 0, 8},
+ { 12000000, 600000000, 600, 12, 0, 8},
+ { 13000000, 600000000, 600, 13, 0, 8},
+ { 19200000, 600000000, 375, 12, 0, 6},
+ { 26000000, 600000000, 600, 26, 0, 8},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
- { 12000000, 216000000, 432, 12, 2, 8},
- { 13000000, 216000000, 432, 13, 2, 8},
- { 19200000, 216000000, 90, 4, 2, 1},
- { 26000000, 216000000, 432, 26, 2, 8},
- { 12000000, 432000000, 432, 12, 1, 8},
- { 13000000, 432000000, 432, 13, 1, 8},
- { 19200000, 432000000, 90, 4, 1, 1},
- { 26000000, 432000000, 432, 26, 1, 8},
+ { 12000000, 216000000, 432, 12, 1, 8},
+ { 13000000, 216000000, 432, 13, 1, 8},
+ { 19200000, 216000000, 90, 4, 1, 1},
+ { 26000000, 216000000, 432, 26, 1, 8},
+ { 12000000, 432000000, 432, 12, 0, 8},
+ { 13000000, 432000000, 432, 13, 0, 8},
+ { 19200000, 432000000, 90, 4, 0, 1},
+ { 26000000, 432000000, 432, 26, 0, 8},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
- { 28800000, 56448000, 49, 25, 1, 1},
- { 28800000, 73728000, 64, 25, 1, 1},
- { 28800000, 24000000, 5, 6, 1, 1},
+ { 28800000, 56448000, 49, 25, 0, 1},
+ { 28800000, 73728000, 64, 25, 0, 1},
+ { 28800000, 24000000, 5, 6, 0, 1},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
- { 12000000, 216000000, 216, 12, 1, 4},
- { 13000000, 216000000, 216, 13, 1, 4},
- { 19200000, 216000000, 135, 12, 1, 3},
- { 26000000, 216000000, 216, 26, 1, 4},
+ { 12000000, 216000000, 216, 12, 0, 4},
+ { 13000000, 216000000, 216, 13, 0, 4},
+ { 19200000, 216000000, 135, 12, 0, 3},
+ { 26000000, 216000000, 216, 26, 0, 4},
- { 12000000, 594000000, 594, 12, 1, 8},
- { 13000000, 594000000, 594, 13, 1, 8},
- { 19200000, 594000000, 495, 16, 1, 8},
- { 26000000, 594000000, 594, 26, 1, 8},
+ { 12000000, 594000000, 594, 12, 0, 8},
+ { 13000000, 594000000, 594, 13, 0, 8},
+ { 19200000, 594000000, 495, 16, 0, 8},
+ { 26000000, 594000000, 594, 26, 0, 8},
- { 12000000, 1000000000, 1000, 12, 1, 12},
- { 13000000, 1000000000, 1000, 13, 1, 12},
- { 19200000, 1000000000, 625, 12, 1, 8},
- { 26000000, 1000000000, 1000, 26, 1, 12},
+ { 12000000, 1000000000, 1000, 12, 0, 12},
+ { 13000000, 1000000000, 1000, 13, 0, 12},
+ { 19200000, 1000000000, 625, 12, 0, 8},
+ { 26000000, 1000000000, 1000, 26, 0, 12},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
- { 12000000, 480000000, 960, 12, 2, 0},
- { 13000000, 480000000, 960, 13, 2, 0},
- { 19200000, 480000000, 200, 4, 2, 0},
- { 26000000, 480000000, 960, 26, 2, 0},
+ { 12000000, 480000000, 960, 12, 0, 0},
+ { 13000000, 480000000, 960, 13, 0, 0},
+ { 19200000, 480000000, 200, 4, 0, 0},
+ { 26000000, 480000000, 960, 26, 0, 0},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
/* 1 GHz */
- { 12000000, 1000000000, 1000, 12, 1, 12},
- { 13000000, 1000000000, 1000, 13, 1, 12},
- { 19200000, 1000000000, 625, 12, 1, 8},
- { 26000000, 1000000000, 1000, 26, 1, 12},
+ { 12000000, 1000000000, 1000, 12, 0, 12},
+ { 13000000, 1000000000, 1000, 13, 0, 12},
+ { 19200000, 1000000000, 625, 12, 0, 8},
+ { 26000000, 1000000000, 1000, 26, 0, 12},
/* 912 MHz */
- { 12000000, 912000000, 912, 12, 1, 12},
- { 13000000, 912000000, 912, 13, 1, 12},
- { 19200000, 912000000, 760, 16, 1, 8},
- { 26000000, 912000000, 912, 26, 1, 12},
+ { 12000000, 912000000, 912, 12, 0, 12},
+ { 13000000, 912000000, 912, 13, 0, 12},
+ { 19200000, 912000000, 760, 16, 0, 8},
+ { 26000000, 912000000, 912, 26, 0, 12},
/* 816 MHz */
- { 12000000, 816000000, 816, 12, 1, 12},
- { 13000000, 816000000, 816, 13, 1, 12},
- { 19200000, 816000000, 680, 16, 1, 8},
- { 26000000, 816000000, 816, 26, 1, 12},
+ { 12000000, 816000000, 816, 12, 0, 12},
+ { 13000000, 816000000, 816, 13, 0, 12},
+ { 19200000, 816000000, 680, 16, 0, 8},
+ { 26000000, 816000000, 816, 26, 0, 12},
/* 760 MHz */
- { 12000000, 760000000, 760, 12, 1, 12},
- { 13000000, 760000000, 760, 13, 1, 12},
- { 19200000, 760000000, 950, 24, 1, 8},
- { 26000000, 760000000, 760, 26, 1, 12},
+ { 12000000, 760000000, 760, 12, 0, 12},
+ { 13000000, 760000000, 760, 13, 0, 12},
+ { 19200000, 760000000, 950, 24, 0, 8},
+ { 26000000, 760000000, 760, 26, 0, 12},
/* 750 MHz */
- { 12000000, 750000000, 750, 12, 1, 12},
- { 13000000, 750000000, 750, 13, 1, 12},
- { 19200000, 750000000, 625, 16, 1, 8},
- { 26000000, 750000000, 750, 26, 1, 12},
+ { 12000000, 750000000, 750, 12, 0, 12},
+ { 13000000, 750000000, 750, 13, 0, 12},
+ { 19200000, 750000000, 625, 16, 0, 8},
+ { 26000000, 750000000, 750, 26, 0, 12},
/* 608 MHz */
- { 12000000, 608000000, 608, 12, 1, 12},
- { 13000000, 608000000, 608, 13, 1, 12},
- { 19200000, 608000000, 380, 12, 1, 8},
- { 26000000, 608000000, 608, 26, 1, 12},
+ { 12000000, 608000000, 608, 12, 0, 12},
+ { 13000000, 608000000, 608, 13, 0, 12},
+ { 19200000, 608000000, 380, 12, 0, 8},
+ { 26000000, 608000000, 608, 26, 0, 12},
/* 456 MHz */
- { 12000000, 456000000, 456, 12, 1, 12},
- { 13000000, 456000000, 456, 13, 1, 12},
- { 19200000, 456000000, 380, 16, 1, 8},
- { 26000000, 456000000, 456, 26, 1, 12},
+ { 12000000, 456000000, 456, 12, 0, 12},
+ { 13000000, 456000000, 456, 13, 0, 12},
+ { 19200000, 456000000, 380, 16, 0, 8},
+ { 26000000, 456000000, 456, 26, 0, 12},
/* 312 MHz */
- { 12000000, 312000000, 312, 12, 1, 12},
- { 13000000, 312000000, 312, 13, 1, 12},
- { 19200000, 312000000, 260, 16, 1, 8},
- { 26000000, 312000000, 312, 26, 1, 12},
+ { 12000000, 312000000, 312, 12, 0, 12},
+ { 13000000, 312000000, 312, 13, 0, 12},
+ { 19200000, 312000000, 260, 16, 0, 8},
+ { 26000000, 312000000, 312, 26, 0, 12},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
- { 12000000, 100000000, 200, 24, 1, 0 },
+ { 12000000, 100000000, 200, 24, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
};
.vco_max = 1400000000,
.base_reg = PLLC_BASE,
.misc_reg = PLLC_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1200000000,
.base_reg = PLLM_BASE,
.misc_reg = PLLM_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1400000000,
.base_reg = PLLP_BASE,
.misc_reg = PLLP_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1400000000,
.base_reg = PLLA_BASE,
.misc_reg = PLLA_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1000000000,
.base_reg = PLLD_BASE,
.misc_reg = PLLD_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
.lock_delay = 1000,
};
+static struct pdiv_map pllu_p[] = {
+ { .pdiv = 1, .hw_val = 1 },
+ { .pdiv = 2, .hw_val = 0 },
+ { .pdiv = 0, .hw_val = 0 },
+};
+
static struct tegra_clk_pll_params pll_u_params = {
.input_min = 2000000,
.input_max = 40000000,
.vco_max = 960000000,
.base_reg = PLLU_BASE,
.misc_reg = PLLU_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
.lock_delay = 1000,
+ .pdiv_tohw = pllu_p,
};
static struct tegra_clk_pll_params pll_x_params = {
.vco_max = 1200000000,
.base_reg = PLLX_BASE,
.misc_reg = PLLX_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 0,
.base_reg = PLLE_BASE,
.misc_reg = PLLE_MISC,
- .lock_bit_idx = PLLE_MISC_LOCK,
+ .lock_mask = PLLE_MISC_LOCK,
.lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
.lock_delay = 0,
};
}
static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
- "pll_p_cclk", "pll_p_out4_cclk",
- "pll_p_out3_cclk", "clk_d", "pll_x" };
+ "pll_p", "pll_p_out4",
+ "pll_p_out3", "clk_d", "pll_x" };
static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
"pll_p_out3", "pll_p_out2", "clk_d",
"clk_32k", "pll_m_out1" };
{
struct clk *clk;
- /*
- * DIV_U71 dividers for CCLK, these dividers are used only
- * if parent clock is fixed rate.
- */
-
- /*
- * Clock input to cclk divided from pll_p using
- * U71 divider of cclk.
- */
- clk = tegra_clk_register_divider("pll_p_cclk", "pll_p",
- clk_base + SUPER_CCLK_DIVIDER, 0,
- TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
- clk_register_clkdev(clk, "pll_p_cclk", NULL);
-
- /*
- * Clock input to cclk divided from pll_p_out3 using
- * U71 divider of cclk.
- */
- clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3",
- clk_base + SUPER_CCLK_DIVIDER, 0,
- TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
- clk_register_clkdev(clk, "pll_p_out3_cclk", NULL);
-
- /*
- * Clock input to cclk divided from pll_p_out4 using
- * U71 divider of cclk.
- */
- clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4",
- clk_base + SUPER_CCLK_DIVIDER, 0,
- TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
- clk_register_clkdev(clk, "pll_p_out4_cclk", NULL);
-
/* CCLK */
clk = tegra_clk_register_super_mux("cclk", cclk_parents,
ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
data = &tegra_periph_clk_list[i];
clk = tegra_clk_register_periph(data->name, data->parent_names,
data->num_parents, &data->periph,
- clk_base, data->offset);
+ clk_base, data->offset, data->flags);
clk_register_clkdev(clk, data->con_id, data->dev_id);
clks[data->clk_id] = clk;
}
{host1x, pll_c, 150000000, 0},
{disp1, pll_p, 600000000, 0},
{disp2, pll_p, 600000000, 0},
+ {gr2d, pll_c, 300000000, 0},
+ {gr3d, pll_c, 300000000, 0},
{clk_max, clk_max, 0, 0}, /* This MUST be the last entry */
};
+static void __init tegra20_clock_apply_init_table(void)
+{
+ tegra_init_from_table(init_table, clks, clk_max);
+}
+
/*
* Some clocks may be used by different drivers depending on the board
* configuration. List those here to register them twice in the clock lookup
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- tegra_init_from_table(init_table, clks, clk_max);
+ tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
tegra_cpu_car_ops = &tegra20_cpu_car_ops;
}
#define PLLDU_MISC_LOCK_ENABLE 22
#define PLLE_MISC_LOCK_ENABLE 9
-#define PLL_BASE_LOCK 27
-#define PLLE_MISC_LOCK 11
+#define PLL_BASE_LOCK BIT(27)
+#define PLLE_MISC_LOCK BIT(11)
#define PLLE_AUX 0x48c
#define PLLC_OUT 0x84
usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2cslow,
dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92,
- cdev1, cdev2, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4,
+ cdev2, cdev1, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4,
i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x,
atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x,
spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda,
};
static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
- { 12000000, 1040000000, 520, 6, 1, 8},
- { 13000000, 1040000000, 480, 6, 1, 8},
- { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */
- { 19200000, 1040000000, 325, 6, 1, 6},
- { 26000000, 1040000000, 520, 13, 1, 8},
-
- { 12000000, 832000000, 416, 6, 1, 8},
- { 13000000, 832000000, 832, 13, 1, 8},
- { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */
- { 19200000, 832000000, 260, 6, 1, 8},
- { 26000000, 832000000, 416, 13, 1, 8},
-
- { 12000000, 624000000, 624, 12, 1, 8},
- { 13000000, 624000000, 624, 13, 1, 8},
- { 16800000, 600000000, 520, 14, 1, 8},
- { 19200000, 624000000, 520, 16, 1, 8},
- { 26000000, 624000000, 624, 26, 1, 8},
-
- { 12000000, 600000000, 600, 12, 1, 8},
- { 13000000, 600000000, 600, 13, 1, 8},
- { 16800000, 600000000, 500, 14, 1, 8},
- { 19200000, 600000000, 375, 12, 1, 6},
- { 26000000, 600000000, 600, 26, 1, 8},
-
- { 12000000, 520000000, 520, 12, 1, 8},
- { 13000000, 520000000, 520, 13, 1, 8},
- { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */
- { 19200000, 520000000, 325, 12, 1, 6},
- { 26000000, 520000000, 520, 26, 1, 8},
-
- { 12000000, 416000000, 416, 12, 1, 8},
- { 13000000, 416000000, 416, 13, 1, 8},
- { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */
- { 19200000, 416000000, 260, 12, 1, 6},
- { 26000000, 416000000, 416, 26, 1, 8},
+ { 12000000, 1040000000, 520, 6, 0, 8},
+ { 13000000, 1040000000, 480, 6, 0, 8},
+ { 16800000, 1040000000, 495, 8, 0, 8}, /* actual: 1039.5 MHz */
+ { 19200000, 1040000000, 325, 6, 0, 6},
+ { 26000000, 1040000000, 520, 13, 0, 8},
+
+ { 12000000, 832000000, 416, 6, 0, 8},
+ { 13000000, 832000000, 832, 13, 0, 8},
+ { 16800000, 832000000, 396, 8, 0, 8}, /* actual: 831.6 MHz */
+ { 19200000, 832000000, 260, 6, 0, 8},
+ { 26000000, 832000000, 416, 13, 0, 8},
+
+ { 12000000, 624000000, 624, 12, 0, 8},
+ { 13000000, 624000000, 624, 13, 0, 8},
+ { 16800000, 600000000, 520, 14, 0, 8},
+ { 19200000, 624000000, 520, 16, 0, 8},
+ { 26000000, 624000000, 624, 26, 0, 8},
+
+ { 12000000, 600000000, 600, 12, 0, 8},
+ { 13000000, 600000000, 600, 13, 0, 8},
+ { 16800000, 600000000, 500, 14, 0, 8},
+ { 19200000, 600000000, 375, 12, 0, 6},
+ { 26000000, 600000000, 600, 26, 0, 8},
+
+ { 12000000, 520000000, 520, 12, 0, 8},
+ { 13000000, 520000000, 520, 13, 0, 8},
+ { 16800000, 520000000, 495, 16, 0, 8}, /* actual: 519.75 MHz */
+ { 19200000, 520000000, 325, 12, 0, 6},
+ { 26000000, 520000000, 520, 26, 0, 8},
+
+ { 12000000, 416000000, 416, 12, 0, 8},
+ { 13000000, 416000000, 416, 13, 0, 8},
+ { 16800000, 416000000, 396, 16, 0, 8}, /* actual: 415.8 MHz */
+ { 19200000, 416000000, 260, 12, 0, 6},
+ { 26000000, 416000000, 416, 26, 0, 8},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
- { 12000000, 666000000, 666, 12, 1, 8},
- { 13000000, 666000000, 666, 13, 1, 8},
- { 16800000, 666000000, 555, 14, 1, 8},
- { 19200000, 666000000, 555, 16, 1, 8},
- { 26000000, 666000000, 666, 26, 1, 8},
- { 12000000, 600000000, 600, 12, 1, 8},
- { 13000000, 600000000, 600, 13, 1, 8},
- { 16800000, 600000000, 500, 14, 1, 8},
- { 19200000, 600000000, 375, 12, 1, 6},
- { 26000000, 600000000, 600, 26, 1, 8},
+ { 12000000, 666000000, 666, 12, 0, 8},
+ { 13000000, 666000000, 666, 13, 0, 8},
+ { 16800000, 666000000, 555, 14, 0, 8},
+ { 19200000, 666000000, 555, 16, 0, 8},
+ { 26000000, 666000000, 666, 26, 0, 8},
+ { 12000000, 600000000, 600, 12, 0, 8},
+ { 13000000, 600000000, 600, 13, 0, 8},
+ { 16800000, 600000000, 500, 14, 0, 8},
+ { 19200000, 600000000, 375, 12, 0, 6},
+ { 26000000, 600000000, 600, 26, 0, 8},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
- { 12000000, 216000000, 432, 12, 2, 8},
- { 13000000, 216000000, 432, 13, 2, 8},
- { 16800000, 216000000, 360, 14, 2, 8},
- { 19200000, 216000000, 360, 16, 2, 8},
- { 26000000, 216000000, 432, 26, 2, 8},
+ { 12000000, 216000000, 432, 12, 1, 8},
+ { 13000000, 216000000, 432, 13, 1, 8},
+ { 16800000, 216000000, 360, 14, 1, 8},
+ { 19200000, 216000000, 360, 16, 1, 8},
+ { 26000000, 216000000, 432, 26, 1, 8},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
- { 9600000, 564480000, 294, 5, 1, 4},
- { 9600000, 552960000, 288, 5, 1, 4},
- { 9600000, 24000000, 5, 2, 1, 1},
+ { 9600000, 564480000, 294, 5, 0, 4},
+ { 9600000, 552960000, 288, 5, 0, 4},
+ { 9600000, 24000000, 5, 2, 0, 1},
- { 28800000, 56448000, 49, 25, 1, 1},
- { 28800000, 73728000, 64, 25, 1, 1},
- { 28800000, 24000000, 5, 6, 1, 1},
+ { 28800000, 56448000, 49, 25, 0, 1},
+ { 28800000, 73728000, 64, 25, 0, 1},
+ { 28800000, 24000000, 5, 6, 0, 1},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
- { 12000000, 216000000, 216, 12, 1, 4},
- { 13000000, 216000000, 216, 13, 1, 4},
- { 16800000, 216000000, 180, 14, 1, 4},
- { 19200000, 216000000, 180, 16, 1, 4},
- { 26000000, 216000000, 216, 26, 1, 4},
-
- { 12000000, 594000000, 594, 12, 1, 8},
- { 13000000, 594000000, 594, 13, 1, 8},
- { 16800000, 594000000, 495, 14, 1, 8},
- { 19200000, 594000000, 495, 16, 1, 8},
- { 26000000, 594000000, 594, 26, 1, 8},
-
- { 12000000, 1000000000, 1000, 12, 1, 12},
- { 13000000, 1000000000, 1000, 13, 1, 12},
- { 19200000, 1000000000, 625, 12, 1, 8},
- { 26000000, 1000000000, 1000, 26, 1, 12},
+ { 12000000, 216000000, 216, 12, 0, 4},
+ { 13000000, 216000000, 216, 13, 0, 4},
+ { 16800000, 216000000, 180, 14, 0, 4},
+ { 19200000, 216000000, 180, 16, 0, 4},
+ { 26000000, 216000000, 216, 26, 0, 4},
+
+ { 12000000, 594000000, 594, 12, 0, 8},
+ { 13000000, 594000000, 594, 13, 0, 8},
+ { 16800000, 594000000, 495, 14, 0, 8},
+ { 19200000, 594000000, 495, 16, 0, 8},
+ { 26000000, 594000000, 594, 26, 0, 8},
+
+ { 12000000, 1000000000, 1000, 12, 0, 12},
+ { 13000000, 1000000000, 1000, 13, 0, 12},
+ { 19200000, 1000000000, 625, 12, 0, 8},
+ { 26000000, 1000000000, 1000, 26, 0, 12},
{ 0, 0, 0, 0, 0, 0 },
};
+static struct pdiv_map pllu_p[] = {
+ { .pdiv = 1, .hw_val = 1 },
+ { .pdiv = 2, .hw_val = 0 },
+ { .pdiv = 0, .hw_val = 0 },
+};
+
static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
- { 12000000, 480000000, 960, 12, 2, 12},
- { 13000000, 480000000, 960, 13, 2, 12},
- { 16800000, 480000000, 400, 7, 2, 5},
- { 19200000, 480000000, 200, 4, 2, 3},
- { 26000000, 480000000, 960, 26, 2, 12},
+ { 12000000, 480000000, 960, 12, 0, 12},
+ { 13000000, 480000000, 960, 13, 0, 12},
+ { 16800000, 480000000, 400, 7, 0, 5},
+ { 19200000, 480000000, 200, 4, 0, 3},
+ { 26000000, 480000000, 960, 26, 0, 12},
{ 0, 0, 0, 0, 0, 0 },
};
static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
/* 1.7 GHz */
- { 12000000, 1700000000, 850, 6, 1, 8},
- { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */
- { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */
- { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */
- { 26000000, 1700000000, 850, 13, 1, 8},
+ { 12000000, 1700000000, 850, 6, 0, 8},
+ { 13000000, 1700000000, 915, 7, 0, 8}, /* actual: 1699.2 MHz */
+ { 16800000, 1700000000, 708, 7, 0, 8}, /* actual: 1699.2 MHz */
+ { 19200000, 1700000000, 885, 10, 0, 8}, /* actual: 1699.2 MHz */
+ { 26000000, 1700000000, 850, 13, 0, 8},
/* 1.6 GHz */
- { 12000000, 1600000000, 800, 6, 1, 8},
- { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */
- { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */
- { 19200000, 1600000000, 500, 6, 1, 8},
- { 26000000, 1600000000, 800, 13, 1, 8},
+ { 12000000, 1600000000, 800, 6, 0, 8},
+ { 13000000, 1600000000, 738, 6, 0, 8}, /* actual: 1599.0 MHz */
+ { 16800000, 1600000000, 857, 9, 0, 8}, /* actual: 1599.7 MHz */
+ { 19200000, 1600000000, 500, 6, 0, 8},
+ { 26000000, 1600000000, 800, 13, 0, 8},
/* 1.5 GHz */
- { 12000000, 1500000000, 750, 6, 1, 8},
- { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */
- { 16800000, 1500000000, 625, 7, 1, 8},
- { 19200000, 1500000000, 625, 8, 1, 8},
- { 26000000, 1500000000, 750, 13, 1, 8},
+ { 12000000, 1500000000, 750, 6, 0, 8},
+ { 13000000, 1500000000, 923, 8, 0, 8}, /* actual: 1499.8 MHz */
+ { 16800000, 1500000000, 625, 7, 0, 8},
+ { 19200000, 1500000000, 625, 8, 0, 8},
+ { 26000000, 1500000000, 750, 13, 0, 8},
/* 1.4 GHz */
- { 12000000, 1400000000, 700, 6, 1, 8},
- { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */
- { 16800000, 1400000000, 1000, 12, 1, 8},
- { 19200000, 1400000000, 875, 12, 1, 8},
- { 26000000, 1400000000, 700, 13, 1, 8},
+ { 12000000, 1400000000, 700, 6, 0, 8},
+ { 13000000, 1400000000, 969, 9, 0, 8}, /* actual: 1399.7 MHz */
+ { 16800000, 1400000000, 1000, 12, 0, 8},
+ { 19200000, 1400000000, 875, 12, 0, 8},
+ { 26000000, 1400000000, 700, 13, 0, 8},
/* 1.3 GHz */
- { 12000000, 1300000000, 975, 9, 1, 8},
- { 13000000, 1300000000, 1000, 10, 1, 8},
- { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */
- { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */
- { 26000000, 1300000000, 650, 13, 1, 8},
+ { 12000000, 1300000000, 975, 9, 0, 8},
+ { 13000000, 1300000000, 1000, 10, 0, 8},
+ { 16800000, 1300000000, 928, 12, 0, 8}, /* actual: 1299.2 MHz */
+ { 19200000, 1300000000, 812, 12, 0, 8}, /* actual: 1299.2 MHz */
+ { 26000000, 1300000000, 650, 13, 0, 8},
/* 1.2 GHz */
- { 12000000, 1200000000, 1000, 10, 1, 8},
- { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */
- { 16800000, 1200000000, 1000, 14, 1, 8},
- { 19200000, 1200000000, 1000, 16, 1, 8},
- { 26000000, 1200000000, 600, 13, 1, 8},
+ { 12000000, 1200000000, 1000, 10, 0, 8},
+ { 13000000, 1200000000, 923, 10, 0, 8}, /* actual: 1199.9 MHz */
+ { 16800000, 1200000000, 1000, 14, 0, 8},
+ { 19200000, 1200000000, 1000, 16, 0, 8},
+ { 26000000, 1200000000, 600, 13, 0, 8},
/* 1.1 GHz */
- { 12000000, 1100000000, 825, 9, 1, 8},
- { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */
- { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */
- { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */
- { 26000000, 1100000000, 550, 13, 1, 8},
+ { 12000000, 1100000000, 825, 9, 0, 8},
+ { 13000000, 1100000000, 846, 10, 0, 8}, /* actual: 1099.8 MHz */
+ { 16800000, 1100000000, 982, 15, 0, 8}, /* actual: 1099.8 MHz */
+ { 19200000, 1100000000, 859, 15, 0, 8}, /* actual: 1099.5 MHz */
+ { 26000000, 1100000000, 550, 13, 0, 8},
/* 1 GHz */
- { 12000000, 1000000000, 1000, 12, 1, 8},
- { 13000000, 1000000000, 1000, 13, 1, 8},
- { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */
- { 19200000, 1000000000, 625, 12, 1, 8},
- { 26000000, 1000000000, 1000, 26, 1, 8},
+ { 12000000, 1000000000, 1000, 12, 0, 8},
+ { 13000000, 1000000000, 1000, 13, 0, 8},
+ { 16800000, 1000000000, 833, 14, 0, 8}, /* actual: 999.6 MHz */
+ { 19200000, 1000000000, 625, 12, 0, 8},
+ { 26000000, 1000000000, 1000, 26, 0, 8},
{ 0, 0, 0, 0, 0, 0 },
};
.vco_max = 1400000000,
.base_reg = PLLC_BASE,
.misc_reg = PLLC_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1200000000,
.base_reg = PLLM_BASE,
.misc_reg = PLLM_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1400000000,
.base_reg = PLLP_BASE,
.misc_reg = PLLP_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1400000000,
.base_reg = PLLA_BASE,
.misc_reg = PLLA_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 1000000000,
.base_reg = PLLD_BASE,
.misc_reg = PLLD_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
.lock_delay = 1000,
};
.vco_max = 1000000000,
.base_reg = PLLD2_BASE,
.misc_reg = PLLD2_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
.lock_delay = 1000,
};
.vco_max = 960000000,
.base_reg = PLLU_BASE,
.misc_reg = PLLU_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
.lock_delay = 1000,
+ .pdiv_tohw = pllu_p,
};
static struct tegra_clk_pll_params pll_x_params = {
.vco_max = 1700000000,
.base_reg = PLLX_BASE,
.misc_reg = PLLX_MISC,
- .lock_bit_idx = PLL_BASE_LOCK,
+ .lock_mask = PLL_BASE_LOCK,
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
.vco_max = 2400000000U,
.base_reg = PLLE_BASE,
.misc_reg = PLLE_MISC,
- .lock_bit_idx = PLLE_MISC_LOCK,
+ .lock_mask = PLLE_MISC_LOCK,
.lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
.lock_delay = 300,
};
data = &tegra_periph_clk_list[i];
clk = tegra_clk_register_periph(data->name, data->parent_names,
data->num_parents, &data->periph,
- clk_base, data->offset);
+ clk_base, data->offset, data->flags);
clk_register_clkdev(clk, data->con_id, data->dev_id);
clks[data->clk_id] = clk;
}
{disp1, pll_p, 600000000, 0},
{disp2, pll_p, 600000000, 0},
{twd, clk_max, 0, 1},
+ {gr2d, pll_c, 300000000, 0},
+ {gr3d, pll_c, 300000000, 0},
{clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */
};
+static void __init tegra30_clock_apply_init_table(void)
+{
+ tegra_init_from_table(init_table, clks, clk_max);
+}
+
/*
* Some clocks may be used by different drivers depending on the board
* configuration. List those here to register them twice in the clock lookup
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- tegra_init_from_table(init_table, clks, clk_max);
+ tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
tegra_cpu_car_ops = &tegra30_cpu_car_ops;
}
#include "clk.h"
/* Global data of Tegra CPU CAR ops */
-struct tegra_cpu_car_ops *tegra_cpu_car_ops;
+static struct tegra_cpu_car_ops dummy_car_ops;
+struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
struct clk *clks[], int clk_max)
static const struct of_device_id tegra_dt_clk_match[] = {
{ .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init },
{ .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init },
+ { .compatible = "nvidia,tegra114-car", .data = tegra114_clock_init },
{ }
};
{
of_clk_init(tegra_dt_clk_match);
}
+
+tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
+
+void __init tegra_clocks_apply_init_table(void)
+{
+ if (!tegra_clk_apply_init_table)
+ return;
+
+ tegra_clk_apply_init_table();
+}
-/*
+ /*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
u8 cpcon;
};
+/**
+ * struct pdiv_map - map post divider to hw value
+ *
+ * @pdiv: post divider
+ * @hw_val: value to be written to the PLL hw
+ */
+struct pdiv_map {
+ u8 pdiv;
+ u8 hw_val;
+};
+
/**
* struct clk_pll_params - PLL parameters
*
u32 base_reg;
u32 misc_reg;
u32 lock_reg;
- u32 lock_bit_idx;
+ u32 lock_mask;
u32 lock_enable_bit_idx;
+ u32 iddq_reg;
+ u32 iddq_bit_idx;
+ u32 aux_reg;
+ u32 dyn_ramp_reg;
+ u32 ext_misc_reg[3];
+ int stepa_shift;
+ int stepb_shift;
int lock_delay;
+ int max_p;
+ struct pdiv_map *pdiv_tohw;
};
/**
* TEGRA_PLL_FIXED - We are not supposed to change output frequency
* of some plls.
* TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
+ * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
+ * base register.
+ * TEGRA_PLL_BYPASS - PLL has bypass bit
+ * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
*/
struct tegra_clk_pll {
struct clk_hw hw;
void __iomem *clk_base;
void __iomem *pmc;
- u8 flags;
+ u32 flags;
unsigned long fixed_rate;
spinlock_t *lock;
u8 divn_shift;
#define TEGRA_PLLM BIT(5)
#define TEGRA_PLL_FIXED BIT(6)
#define TEGRA_PLLE_CONFIGURE BIT(7)
+#define TEGRA_PLL_LOCK_MISC BIT(8)
+#define TEGRA_PLL_BYPASS BIT(9)
+#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
extern const struct clk_ops tegra_clk_pll_ops;
extern const struct clk_ops tegra_clk_plle_ops;
struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
unsigned long flags, unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_params *pll_params, u32 pll_flags,
struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
+
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
unsigned long flags, unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_params *pll_params, u32 pll_flags,
struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
+struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ u32 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock, unsigned long parent_rate);
+
+struct clk *tegra_clk_register_plle_tegra114(const char *name,
+ const char *parent_name,
+ void __iomem *clk_base, unsigned long flags,
+ unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params,
+ struct tegra_clk_pll_freq_table *freq_table,
+ spinlock_t *lock);
+
/**
* struct tegra_clk_pll_out - PLL divider down clock
*
* TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the
* bus to flush the write operation in apb bus. This flag indicates
* that this peripheral is in apb bus.
+ * TEGRA_PERIPH_WAR_1005168 - Apply workaround for Tegra114 MSENC bug
*/
struct tegra_clk_periph_gate {
u32 magic;
#define TEGRA_PERIPH_NO_RESET BIT(0)
#define TEGRA_PERIPH_MANUAL_RESET BIT(1)
#define TEGRA_PERIPH_ON_APB BIT(2)
+#define TEGRA_PERIPH_WAR_1005168 BIT(3)
void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
extern const struct clk_ops tegra_clk_periph_gate_ops;
struct clk *tegra_clk_register_periph(const char *name,
const char **parent_names, int num_parents,
struct tegra_clk_periph *periph, void __iomem *clk_base,
- u32 offset);
+ u32 offset, unsigned long flags);
struct clk *tegra_clk_register_periph_nodiv(const char *name,
const char **parent_names, int num_parents,
struct tegra_clk_periph *periph, void __iomem *clk_base,
u32 offset);
-#define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \
+#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \
_div_shift, _div_width, _div_frac_width, \
_div_flags, _clk_num, _enb_refcnt, _regs, \
- _gate_flags) \
+ _gate_flags, _table) \
{ \
.mux = { \
.flags = _mux_flags, \
.shift = _mux_shift, \
- .width = _mux_width, \
+ .mask = _mux_mask, \
+ .table = _table, \
}, \
.divider = { \
.flags = _div_flags, \
u32 offset;
const char *con_id;
const char *dev_id;
+ unsigned long flags;
};
-#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \
- _mux_shift, _mux_width, _mux_flags, _div_shift, \
+#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, _mux_mask, _mux_flags, _div_shift, \
_div_width, _div_frac_width, _div_flags, _regs, \
- _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
+ _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\
+ _flags) \
{ \
.name = _name, \
.clk_id = _clk_id, \
.parent_names = _parent_names, \
.num_parents = ARRAY_SIZE(_parent_names), \
- .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \
+ .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \
_mux_flags, _div_shift, \
_div_width, _div_frac_width, \
_div_flags, _clk_num, \
_enb_refcnt, _regs, \
- _gate_flags), \
+ _gate_flags, _table), \
.offset = _offset, \
.con_id = _con_id, \
.dev_id = _dev_id, \
+ .flags = _flags \
}
+#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, _mux_width, _mux_flags, _div_shift, \
+ _div_width, _div_frac_width, _div_flags, _regs, \
+ _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \
+ _div_shift, _div_width, _div_frac_width, _div_flags, \
+ _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\
+ NULL, 0)
+
/**
* struct clk_super_mux - super clock
*
static inline void tegra30_clock_init(struct device_node *np) {}
#endif /* CONFIG_ARCH_TEGRA_3x_SOC */
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+void tegra114_clock_init(struct device_node *np);
+#else
+static inline void tegra114_clock_init(struct device_node *np) {}
+#endif /* CONFIG_ARCH_TEGRA114_SOC */
+
+typedef void (*tegra_clk_apply_init_table_func)(void);
+extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
+
#endif /* TEGRA_CLK_H */
struct clk_prcmu {
struct clk_hw hw;
u8 cg_sel;
+ int is_prepared;
int is_enabled;
+ int opp_requested;
};
/* PRCMU clock operations. */
static int clk_prcmu_prepare(struct clk_hw *hw)
{
+ int ret;
struct clk_prcmu *clk = to_clk_prcmu(hw);
- return prcmu_request_clock(clk->cg_sel, true);
+
+ ret = prcmu_request_clock(clk->cg_sel, true);
+ if (!ret)
+ clk->is_prepared = 1;
+
+ return ret;;
}
static void clk_prcmu_unprepare(struct clk_hw *hw)
struct clk_prcmu *clk = to_clk_prcmu(hw);
if (prcmu_request_clock(clk->cg_sel, false))
pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
- hw->init->name);
+ __clk_get_name(hw->clk));
+ else
+ clk->is_prepared = 0;
+}
+
+static int clk_prcmu_is_prepared(struct clk_hw *hw)
+{
+ struct clk_prcmu *clk = to_clk_prcmu(hw);
+ return clk->is_prepared;
}
static int clk_prcmu_enable(struct clk_hw *hw)
return prcmu_set_clock_rate(clk->cg_sel, rate);
}
-static int request_ape_opp100(bool enable)
-{
- static int reqs;
- int err = 0;
-
- if (enable) {
- if (!reqs)
- err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
- "clock", 100);
- if (!err)
- reqs++;
- } else {
- reqs--;
- if (!reqs)
- prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
- "clock");
- }
- return err;
-}
-
static int clk_prcmu_opp_prepare(struct clk_hw *hw)
{
int err;
struct clk_prcmu *clk = to_clk_prcmu(hw);
- err = request_ape_opp100(true);
- if (err) {
- pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n",
- __func__, hw->init->name);
- return err;
+ if (!clk->opp_requested) {
+ err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
+ (char *)__clk_get_name(hw->clk),
+ 100);
+ if (err) {
+ pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
+ __func__, __clk_get_name(hw->clk));
+ return err;
+ }
+ clk->opp_requested = 1;
}
err = prcmu_request_clock(clk->cg_sel, true);
- if (err)
- request_ape_opp100(false);
+ if (err) {
+ prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
+ (char *)__clk_get_name(hw->clk));
+ clk->opp_requested = 0;
+ return err;
+ }
- return err;
+ clk->is_prepared = 1;
+ return 0;
}
static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false))
- goto out_error;
- if (request_ape_opp100(false))
- goto out_error;
- return;
-
-out_error:
- pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
- hw->init->name);
+ if (prcmu_request_clock(clk->cg_sel, false)) {
+ pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+ __clk_get_name(hw->clk));
+ return;
+ }
+
+ if (clk->opp_requested) {
+ prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
+ (char *)__clk_get_name(hw->clk));
+ clk->opp_requested = 0;
+ }
+
+ clk->is_prepared = 0;
}
static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
int err;
struct clk_prcmu *clk = to_clk_prcmu(hw);
- err = prcmu_request_ape_opp_100_voltage(true);
- if (err) {
- pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
- __func__, hw->init->name);
- return err;
+ if (!clk->opp_requested) {
+ err = prcmu_request_ape_opp_100_voltage(true);
+ if (err) {
+ pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
+ __func__, __clk_get_name(hw->clk));
+ return err;
+ }
+ clk->opp_requested = 1;
}
err = prcmu_request_clock(clk->cg_sel, true);
- if (err)
+ if (err) {
prcmu_request_ape_opp_100_voltage(false);
+ clk->opp_requested = 0;
+ return err;
+ }
- return err;
+ clk->is_prepared = 1;
+ return 0;
}
static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false))
- goto out_error;
- if (prcmu_request_ape_opp_100_voltage(false))
- goto out_error;
- return;
-
-out_error:
- pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
- hw->init->name);
+ if (prcmu_request_clock(clk->cg_sel, false)) {
+ pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+ __clk_get_name(hw->clk));
+ return;
+ }
+
+ if (clk->opp_requested) {
+ prcmu_request_ape_opp_100_voltage(false);
+ clk->opp_requested = 0;
+ }
+
+ clk->is_prepared = 0;
}
static struct clk_ops clk_prcmu_scalable_ops = {
.prepare = clk_prcmu_prepare,
.unprepare = clk_prcmu_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
static struct clk_ops clk_prcmu_gate_ops = {
.prepare = clk_prcmu_prepare,
.unprepare = clk_prcmu_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
static struct clk_ops clk_prcmu_opp_gate_ops = {
.prepare = clk_prcmu_opp_prepare,
.unprepare = clk_prcmu_opp_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
.prepare = clk_prcmu_opp_volt_prepare,
.unprepare = clk_prcmu_opp_volt_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
}
clk->cg_sel = cg_sel;
+ clk->is_prepared = 1;
clk->is_enabled = 1;
+ clk->opp_requested = 0;
/* "rate" can be used for changing the initial frequency */
if (rate)
prcmu_set_clock_rate(cg_sel, rate);
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
+obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o
obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
}
}
-static struct of_device_id bcm2835_time_match[] __initconst = {
- { .compatible = "brcm,bcm2835-system-timer" },
- {}
-};
-
-static void __init bcm2835_timer_init(void)
+static void __init bcm2835_timer_init(struct device_node *node)
{
- struct device_node *node;
void __iomem *base;
u32 freq;
int irq;
struct bcm2835_timer *timer;
- node = of_find_matching_node(NULL, bcm2835_time_match);
- if (!node)
- panic("No bcm2835 timer node");
-
base = of_iomap(node, 0);
if (!base)
panic("Can't remap registers");
{
struct device_node *np;
const struct of_device_id *match;
- void (*init_func)(void);
+ void (*init_func)(struct device_node *);
for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
init_func = match->data;
- init_func();
+ init_func(np);
}
}
--- /dev/null
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright (C) 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/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/stmp_device.h>
+
+#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
+ * extends the counter to 32 bits.
+ *
+ * The implementation uses two timers, one for clock_event and
+ * another for clocksource. MX28 uses timrot 0 and 1, while MX23
+ * uses 0 and 2.
+ */
+
+#define MX23_TIMROT_VERSION_OFFSET 0x0a0
+#define MX28_TIMROT_VERSION_OFFSET 0x120
+#define BP_TIMROT_MAJOR_VERSION 24
+#define BV_TIMROT_VERSION_1 0x01
+#define BV_TIMROT_VERSION_2 0x02
+#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
+
+/*
+ * There are 4 registers for each timrotv2 instance, and 2 registers
+ * for each timrotv1. So address step 0x40 in macros below strides
+ * one instance of timrotv2 while two instances of timrotv1.
+ *
+ * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
+ * on MX28 while timrot2 on MX23.
+ */
+/* common between v1 and v2 */
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+/* v1 only */
+#define HW_TIMROT_TIMCOUNTn(n) (0x30 + (n) * 0x40)
+/* v2 only */
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
+
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
+#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf
+
+static struct clock_event_device mxs_clockevent_device;
+static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *mxs_timrot_base;
+static u32 timrot_major_version;
+
+static inline void timrot_irq_disable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
+ HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
+ HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_SET);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base +
+ HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+ return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
+ & 0xffff0000) >> 16);
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
+
+ return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
+
+ return 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .dev_id = &mxs_clockevent_device,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] const = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != mxs_clockevent_mode) {
+ /* Set event time into the furthest future */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ pr_info("%s: changing mode from %s to %s\n", __func__,
+ clock_event_mode_label[mxs_clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ mxs_clockevent_mode = mode;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_err("%s: Periodic mode is not implemented\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ timrot_irq_enable();
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device mxs_clockevent_device = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrotv2_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ if (timrot_is_v1())
+ mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
+ mxs_clockevent_device.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&mxs_clockevent_device,
+ clk_get_rate(timer_clk),
+ timrot_is_v1() ? 0xf : 0x2,
+ timrot_is_v1() ? 0xfffe : 0xfffffffe);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrotv1_get_cycles,
+ .mask = CLOCKSOURCE_MASK(16),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static u32 notrace mxs_read_sched_clock_v2(void)
+{
+ return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
+}
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1())
+ clocksource_register_hz(&clocksource_mxs, c);
+ else {
+ clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
+ "mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
+ setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
+ }
+
+ return 0;
+}
+
+static void __init mxs_timer_init(struct device_node *np)
+{
+ struct clk *timer_clk;
+ int irq;
+
+ mxs_timrot_base = of_iomap(np, 0);
+ WARN_ON(!mxs_timrot_base);
+
+ timer_clk = of_clk_get(np, 0);
+ if (IS_ERR(timer_clk)) {
+ pr_err("%s: failed to get clk\n", __func__);
+ return;
+ }
+
+ clk_prepare_enable(timer_clk);
+
+ /*
+ * Initialize timers to a known state
+ */
+ stmp_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
+
+ /* get timrot version */
+ timrot_major_version = __raw_readl(mxs_timrot_base +
+ (of_device_is_compatible(np, "fsl,imx23-timrot") ?
+ MX23_TIMROT_VERSION_OFFSET :
+ MX28_TIMROT_VERSION_OFFSET));
+ timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
+
+ /* one for clock_event */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+
+ /* another for clocksource */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
+
+ /* set clocksource timer fixed count to the maximum */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ irq = irq_of_parse_and_map(np, 0);
+ setup_irq(irq, &mxs_timer_irq);
+}
+CLOCKSOURCE_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init);
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sunxi_timer.h>
-#include <linux/clk-provider.h>
+#include <linux/clk/sunxi.h>
#define TIMER_CTL_REG 0x00
#define TIMER_CTL_ENABLE (1 << 0)
if (irq <= 0)
panic("Can't parse IRQ");
- of_clk_init(NULL);
+ sunxi_init_clocks();
clk = of_clk_get(node, 0);
if (IS_ERR(clk))
.dev_id = &tegra_clockevent,
};
-static const struct of_device_id timer_match[] __initconst = {
- { .compatible = "nvidia,tegra20-timer" },
- {}
-};
-
-static const struct of_device_id rtc_match[] __initconst = {
- { .compatible = "nvidia,tegra20-rtc" },
- {}
-};
-
-static void __init tegra20_init_timer(void)
+static void __init tegra20_init_timer(struct device_node *np)
{
- struct device_node *np;
struct clk *clk;
unsigned long rate;
int ret;
- np = of_find_matching_node(NULL, timer_match);
- if (!np) {
- pr_err("Failed to find timer DT node\n");
- BUG();
- }
-
timer_reg_base = of_iomap(np, 0);
if (!timer_reg_base) {
pr_err("Can't map timer registers\n");
BUG();
}
- clk = clk_get_sys("timer", NULL);
+ clk = of_clk_get(np, 0);
if (IS_ERR(clk)) {
pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
rate = 12000000;
of_node_put(np);
- np = of_find_matching_node(NULL, rtc_match);
- if (!np) {
- pr_err("Failed to find RTC DT node\n");
- BUG();
- }
-
- rtc_base = of_iomap(np, 0);
- if (!rtc_base) {
- pr_err("Can't map RTC registers");
- BUG();
- }
-
- /*
- * rtc registers are used by read_persistent_clock, keep the rtc clock
- * enabled
- */
- clk = clk_get_sys("rtc-tegra", NULL);
- if (IS_ERR(clk))
- pr_warn("Unable to get rtc-tegra clock\n");
- else
- clk_prepare_enable(clk);
-
- of_node_put(np);
-
switch (rate) {
case 12000000:
timer_writel(0x000b, TIMERUS_USEC_CFG);
tegra_clockevent.irq = tegra_timer_irq.irq;
clockevents_config_and_register(&tegra_clockevent, 1000000,
0x1, 0x1fffffff);
-#ifdef CONFIG_HAVE_ARM_TWD
- twd_local_timer_of_register();
-#endif
+}
+CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);
+
+static void __init tegra20_init_rtc(struct device_node *np)
+{
+ struct clk *clk;
+
+ rtc_base = of_iomap(np, 0);
+ if (!rtc_base) {
+ pr_err("Can't map RTC registers");
+ BUG();
+ }
+
+ /*
+ * rtc registers are used by read_persistent_clock, keep the rtc clock
+ * enabled
+ */
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk))
+ pr_warn("Unable to get rtc-tegra clock\n");
+ else
+ clk_prepare_enable(clk);
+
+ of_node_put(np);
+
register_persistent_clock(NULL, tegra_read_persistent_clock);
}
-CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer);
+CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
#ifdef CONFIG_PM
static u32 usec_config;
.dev_id = &clockevent,
};
-static struct of_device_id vt8500_timer_ids[] = {
- { .compatible = "via,vt8500-timer" },
- { }
-};
-
-static void __init vt8500_timer_init(void)
+static void __init vt8500_timer_init(struct device_node *np)
{
- struct device_node *np;
int timer_irq;
- np = of_find_matching_node(NULL, vt8500_timer_ids);
- if (!np) {
- pr_err("%s: Timer description missing from Device Tree\n",
- __func__);
- return;
- }
regbase = of_iomap(np, 0);
if (!regbase) {
pr_err("%s: Missing iobase description in Device Tree\n",
#include <linux/stmp_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_dma.h>
#include <asm/irq.h>
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 {
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int ret;
- if (!data)
- return -EINVAL;
-
- mxs_chan->chan_irq = data->chan_irq;
+ if (data)
+ mxs_chan->chan_irq = data->chan_irq;
mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev,
CCW_BLOCK_SIZE, &mxs_chan->ccw_phys,
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, ¶m);
+}
+
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;
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;
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);
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 */
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 = {
u32 oe[4];
u32 int_enb[4];
u32 int_lvl[4];
+ u32 wake_enb[4];
#endif
};
bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio));
bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio));
bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio));
+
+ /* Enable gpio irq for wake up source */
+ tegra_gpio_writel(bank->wake_enb[p],
+ GPIO_INT_ENB(gpio));
}
}
local_irq_restore(flags);
return 0;
}
-static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
+static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
{
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+ int gpio = d->hwirq;
+ u32 port, bit, mask;
+
+ port = GPIO_PORT(gpio);
+ bit = GPIO_BIT(gpio);
+ mask = BIT(bit);
+
+ if (enable)
+ bank->wake_enb[port] |= mask;
+ else
+ bank->wake_enb[port] &= ~mask;
+
return irq_set_irq_wake(bank->irq, enable);
}
#endif
.irq_unmask = tegra_gpio_irq_unmask,
.irq_set_type = tegra_gpio_irq_set_type,
#ifdef CONFIG_PM_SLEEP
- .irq_set_wake = tegra_gpio_wake_enable,
+ .irq_set_wake = tegra_gpio_irq_set_wake,
#endif
};
#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"
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];
.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 */
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");
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))
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);
}
/* 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;
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o
+obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_METAG) += irq-metag-ext.o
obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o
--- /dev/null
+/*
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/stmp_device.h>
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define HW_ICOLL_VECTOR 0x0000
+#define HW_ICOLL_LEVELACK 0x0010
+#define HW_ICOLL_CTRL 0x0020
+#define HW_ICOLL_STAT_OFFSET 0x0070
+#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
+
+#define ICOLL_NUM_IRQS 128
+
+static void __iomem *icoll_base;
+static struct irq_domain *icoll_domain;
+
+static void icoll_ack_irq(struct irq_data *d)
+{
+ /*
+ * The Interrupt Collector is able to prioritize irqs.
+ * Currently only level 0 is used. So acking can use
+ * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
+ */
+ __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+ icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(struct irq_data *d)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
+}
+
+static void icoll_unmask_irq(struct irq_data *d)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+ .irq_ack = icoll_ack_irq,
+ .irq_mask = icoll_mask_irq,
+ .irq_unmask = icoll_unmask_irq,
+};
+
+asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
+{
+ u32 irqnr;
+
+ do {
+ irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
+ if (irqnr != 0x7f) {
+ __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
+ irqnr = irq_find_mapping(icoll_domain, irqnr);
+ handle_IRQ(irqnr, regs);
+ continue;
+ }
+ break;
+ } while (1);
+}
+
+static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
+ set_irq_flags(virq, IRQF_VALID);
+
+ return 0;
+}
+
+static struct irq_domain_ops icoll_irq_domain_ops = {
+ .map = icoll_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static void __init icoll_of_init(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ icoll_base = of_iomap(np, 0);
+ WARN_ON(!icoll_base);
+
+ /*
+ * Interrupt Collector reset, which initializes the priority
+ * for each irq to level 0.
+ */
+ stmp_reset_block(icoll_base + HW_ICOLL_CTRL);
+
+ icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
+ &icoll_irq_domain_ops, NULL);
+ WARN_ON(!icoll_domain);
+}
+IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init);
#include <linux/dma-mapping.h>
#include <linux/edma.h>
#include <linux/mmc/mmc.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_data/mmc-davinci.h>
dma_cap_set(DMA_SLAVE, mask);
host->dma_tx =
- dma_request_channel(mask, edma_filter_fn, &host->txdma);
+ dma_request_slave_channel_compat(mask, edma_filter_fn,
+ &host->txdma, mmc_dev(host->mmc), "tx");
if (!host->dma_tx) {
dev_err(mmc_dev(host->mmc), "Can't get dma_tx channel\n");
return -ENODEV;
}
host->dma_rx =
- dma_request_channel(mask, edma_filter_fn, &host->rxdma);
+ dma_request_slave_channel_compat(mask, edma_filter_fn,
+ &host->rxdma, mmc_dev(host->mmc), "rx");
if (!host->dma_rx) {
dev_err(mmc_dev(host->mmc), "Can't get dma_rx channel\n");
r = -ENODEV;
mmc_davinci_reset_ctrl(host, 0);
}
-static int __init davinci_mmcsd_probe(struct platform_device *pdev)
+static struct platform_device_id davinci_mmc_devtype[] = {
+ {
+ .name = "dm6441-mmc",
+ .driver_data = MMC_CTLR_VERSION_1,
+ }, {
+ .name = "da830-mmc",
+ .driver_data = MMC_CTLR_VERSION_2,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, davinci_mmc_devtype);
+
+static const struct of_device_id davinci_mmc_dt_ids[] = {
+ {
+ .compatible = "ti,dm6441-mmc",
+ .data = &davinci_mmc_devtype[MMC_CTLR_VERSION_1],
+ },
+ {
+ .compatible = "ti,da830-mmc",
+ .data = &davinci_mmc_devtype[MMC_CTLR_VERSION_2],
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, davinci_mmc_dt_ids);
+
+static struct davinci_mmc_config
+ *mmc_parse_pdata(struct platform_device *pdev)
{
+ struct device_node *np;
struct davinci_mmc_config *pdata = pdev->dev.platform_data;
+ const struct of_device_id *match =
+ of_match_device(of_match_ptr(davinci_mmc_dt_ids), &pdev->dev);
+ u32 data;
+
+ np = pdev->dev.of_node;
+ if (!np)
+ return pdata;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Failed to allocate memory for struct davinci_mmc_config\n");
+ goto nodata;
+ }
+
+ if (match)
+ pdev->id_entry = match->data;
+
+ if (of_property_read_u32(np, "max-frequency", &pdata->max_freq))
+ dev_info(&pdev->dev, "'max-frequency' property not specified, defaulting to 25MHz\n");
+
+ of_property_read_u32(np, "bus-width", &data);
+ switch (data) {
+ case 1:
+ case 4:
+ case 8:
+ pdata->wires = data;
+ break;
+ default:
+ pdata->wires = 1;
+ dev_info(&pdev->dev, "Unsupported buswidth, defaulting to 1 bit\n");
+ }
+nodata:
+ return pdata;
+}
+
+static int __init davinci_mmcsd_probe(struct platform_device *pdev)
+{
+ struct davinci_mmc_config *pdata = NULL;
struct mmc_davinci_host *host = NULL;
struct mmc_host *mmc = NULL;
struct resource *r, *mem = NULL;
int ret = 0, irq = 0;
size_t mem_size;
+ const struct platform_device_id *id_entry;
- /* REVISIT: when we're fully converted, fail if pdata is NULL */
+ pdata = mmc_parse_pdata(pdev);
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "Couldn't get platform data\n");
+ return -ENOENT;
+ }
ret = -ENODEV;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (pdata && (pdata->wires == 8))
mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
- host->version = pdata->version;
+ id_entry = platform_get_device_id(pdev);
+ if (id_entry)
+ host->version = id_entry->driver_data;
mmc->ops = &mmc_davinci_ops;
mmc->f_min = 312500;
.name = "davinci_mmc",
.owner = THIS_MODULE,
.pm = davinci_mmcsd_pm_ops,
+ .of_match_table = of_match_ptr(davinci_mmc_dt_ids),
},
.remove = __exit_p(davinci_mmcsd_remove),
+ .id_table = davinci_mmc_devtype,
};
static int __init davinci_mmcsd_init(void)
.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",
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);
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;
- }
+ ssp->devid = (enum mxs_ssp_id) of_id->data;
host->mmc = mmc;
host->sdio_irq_en = 0;
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__);
#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 };
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;
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;
#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 {
/* 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;
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_ptp);
+ clk_prepare_enable(fep->clk_enet_out);
+ clk_prepare_enable(fep->clk_ptp);
reg_phy = devm_regulator_get(&pdev->dev, "phy");
if (!IS_ERR(reg_phy)) {
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_ptp);
+ clk_disable_unprepare(fep->clk_enet_out);
+ clk_disable_unprepare(fep->clk_ptp);
failed_pin:
failed_clk:
iounmap(fep->hwp);
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++) {
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);
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)) {
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(). */
#include <linux/stmp_device.h>
#include <linux/stmp3xxx_rtc_wdt.h>
-#include <mach/common.h>
-
#define STMP3XXX_RTC_CTRL 0x0
#define STMP3XXX_RTC_CTRL_SET 0x4
#define STMP3XXX_RTC_CTRL_CLR 0x8
platform_set_drvdata(pdev, rtc_data);
- mxs_reset_block(rtc_data->io);
+ stmp_reset_block(rtc_data->io);
writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
{
struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev);
- mxs_reset_block(rtc_data->io);
+ stmp_reset_block(rtc_data->io);
writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
#if defined(CONFIG_OF)
static const struct of_device_id davinci_spi_of_match[] = {
{
- .compatible = "ti,dm644x-spi",
+ .compatible = "ti,dm6441-spi",
},
{
- .compatible = "ti,da8xx-spi",
+ .compatible = "ti,da830-spi",
.data = (void *)SPI_VERSION_2,
},
{ },
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, },
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
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);
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;
+ devid = (enum mxs_ssp_id) of_id->data;
+ ret = of_property_read_u32(np, "clock-frequency",
+ &clk_freq);
+ if (ret)
clk_freq = clk_freq_default;
- }
master = spi_alloc_master(&pdev->dev, sizeof(*spi));
if (!master)
ssp->clk = clk;
ssp->base = base;
ssp->devid = devid;
- ssp->dma_channel = dma_channel;
init_completion(&spi->c);
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;
#include <linux/delay.h>
#include <linux/input.h>
-#include <mach/mxs.h>
-#include <mach/common.h>
-
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#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>
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;
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)
{
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);
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);
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- u32 dma_channel[2];
int ret;
if (!np)
}
s->port.line = ret;
- s->dma_irq_rx = platform_get_irq(pdev, 1);
- s->dma_irq_tx = platform_get_irq(pdev, 2);
+ s->flags |= MXS_AUART_DMA_CONFIG;
- 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;
}
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.
#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
#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)
#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,
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)
{
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);
struct mxsfb_info *host = to_imxfb_host(fb_info);
unsigned loop;
u32 reg;
+ int ret;
dev_dbg(&host->pdev->dev, "%s\n", __func__);
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)
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);
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;
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_size = SZ_2M;
+ fb_virt = alloc_pages_exact(fb_size, GFP_DMA);
+ if (!fb_virt)
+ 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_virt = alloc_pages_exact(fb_size, GFP_DMA);
- if (!fb_virt)
- return -ENOMEM;
-
- fb_phys = virt_to_phys(fb_virt);
- }
+ fb_phys = virt_to_phys(fb_virt);
fb_info->fix.smem_start = fb_phys;
fb_info->screen_base = fb_virt;
{
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);
- }
+ free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
}
static struct platform_device_id mxsfb_devtype[] = {
{
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;
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);
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) {
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;
}
{
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);
}, \
.reg = _reg, \
.shift = _shift, \
- .width = _width, \
+ .mask = BIT(_width) - 1, \
.flags = _mux_flags, \
.lock = _lock, \
}; \
* undo any work done in the @prepare callback. Called with
* prepare_lock held.
*
+ * @is_prepared: Queries the hardware to determine if the clock is prepared.
+ * This function is allowed to sleep. Optional, if this op is not
+ * set then the prepare count will be used.
+ *
+ * @unprepare_unused: Unprepare the clock atomically. Only called from
+ * clk_disable_unused for prepare clocks with special needs.
+ * Called with prepare mutex held. This function may sleep.
+ *
* @enable: Enable the clock atomically. This must not return until the
* clock is generating a valid clock signal, usable by consumer
* devices. Called with enable_lock held. This function must not
struct clk_ops {
int (*prepare)(struct clk_hw *hw);
void (*unprepare)(struct clk_hw *hw);
+ int (*is_prepared)(struct clk_hw *hw);
+ void (*unprepare_unused)(struct clk_hw *hw);
int (*enable)(struct clk_hw *hw);
void (*disable)(struct clk_hw *hw);
int (*is_enabled)(struct clk_hw *hw);
struct clk_mux {
struct clk_hw hw;
void __iomem *reg;
+ u32 *table;
+ u32 mask;
u8 shift;
- u8 width;
u8 flags;
spinlock_t *lock;
};
#define CLK_MUX_INDEX_BIT BIT(1)
extern const struct clk_ops clk_mux_ops;
+
struct clk *clk_register_mux(struct device *dev, const char *name,
const char **parent_names, u8 num_parents, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock);
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u32 mask,
+ u8 clk_mux_flags, u32 *table, spinlock_t *lock);
+
/**
* struct clk_fixed_factor - fixed multiplier and divider clock
*
const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
+/***
+ * struct clk_composite - aggregate clock of mux, divider and gate clocks
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ * @mux_hw: handle between composite and hardware-specifix mux clock
+ * @div_hw: handle between composite and hardware-specifix divider clock
+ * @gate_hw: handle between composite and hardware-specifix gate clock
+ * @mux_ops: clock ops for mux
+ * @div_ops: clock ops for divider
+ * @gate_ops: clock ops for gate
+ */
+struct clk_composite {
+ struct clk_hw hw;
+ struct clk_ops ops;
+
+ struct clk_hw *mux_hw;
+ struct clk_hw *div_hw;
+ struct clk_hw *gate_hw;
+
+ const struct clk_ops *mux_ops;
+ const struct clk_ops *div_ops;
+ const struct clk_ops *gate_ops;
+};
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+ const char **parent_names, int num_parents,
+ struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+ struct clk_hw *div_hw, const struct clk_ops *div_ops,
+ struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+ unsigned long flags);
+
/**
* clk_register - allocate a new clock, register it and return an opaque cookie
* @dev: device that is registering this clock
unsigned int __clk_get_prepare_count(struct clk *clk);
unsigned long __clk_get_rate(struct clk *clk);
unsigned long __clk_get_flags(struct clk *clk);
+bool __clk_is_prepared(struct clk *clk);
bool __clk_is_enabled(struct clk *clk);
struct clk *__clk_lookup(const char *name);
--- /dev/null
+/*
+ * Copyright (C) 2013 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_CLK_MXS_H
+#define __LINUX_CLK_MXS_H
+
+int mx23_clocks_init(void);
+int mx28_clocks_init(void);
+int mxs_saif_clkmux_select(unsigned int clkmux);
+
+#endif
--- /dev/null
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_CLK_SUNXI_H_
+#define __LINUX_CLK_SUNXI_H_
+
+void __init sunxi_init_clocks(void);
+
+#endif
void tegra_periph_reset_deassert(struct clk *c);
void tegra_periph_reset_assert(struct clk *c);
void tegra_clocks_init(void);
+void tegra_clocks_apply_init_table(void);
#endif /* __LINUX_CLK_TEGRA_H_ */
__used __section(__clksrc_of_table) \
= { .compatible = compat, .data = fn };
#else
+static inline void clocksource_of_init(void) {}
#define CLOCKSOURCE_OF_DECLARE(name, compat, fn)
#endif
--- /dev/null
+/*
+ * Copyright (C) 2013 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IRQCHIP_MXS_H
+#define __LINUX_IRQCHIP_MXS_H
+
+extern void icoll_handle_irq(struct pt_regs *);
+
+#endif
} cs[4];
};
+/* Flags for PCI/PCIe address decoding regions */
+#define MVEBU_MBUS_PCI_IO 0x1
+#define MVEBU_MBUS_PCI_MEM 0x2
+#define MVEBU_MBUS_PCI_WA 0x3
+
+/*
+ * Magic value that explicits that we don't need a remapping-capable
+ * address decoding window.
+ */
+#define MVEBU_MBUS_NO_REMAP (0xffffffff)
+
+/* Maximum size of a mbus window name */
+#define MVEBU_MBUS_MAX_WINNAME_SZ 32
+
/*
* The Marvell mbus is to be found only on SOCs from the Orion family
* at the moment. Provide a dummy stub for other architectures.
return NULL;
}
#endif
-#endif
+
+int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
+ size_t size, phys_addr_t remap,
+ unsigned int flags);
+int mvebu_mbus_add_window(const char *devname, phys_addr_t base,
+ size_t size);
+int mvebu_mbus_del_window(phys_addr_t base, size_t size);
+int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
+ size_t mbus_size, phys_addr_t sdram_phys_base,
+ size_t sdram_size);
+
+#endif /* __LINUX_MBUS_H */
+++ /dev/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 */
/* any additional host capabilities: OR'd in to mmc->f_caps */
u32 caps;
- /* Version of the MMC/SD controller */
- u8 version;
-
/* Number of sg segments */
u8 nr_sg;
};
#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)
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];
struct nop_usb_xceiv_platform_data {
enum usb_phy_type type;
+ unsigned long clk_rate;
+
+ /* if set fails with -EPROBE_DEFER if can't get regulator */
+ unsigned int needs_vcc:1;
+ unsigned int needs_reset:1;
};
#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/mxs.h>
#include "mxs-saif.h"
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+
static struct mxs_saif *mxs_saif[2];
/*