+++ /dev/null
-ARM Versatile Express system registers
---------------------------------------
-
-This is a system control registers block, providing multiple low level
-platform functions like board detection and identification, software
-interrupt generation, MMC and NOR Flash control etc.
-
-Required node properties:
-- compatible value : = "arm,vexpress,sysreg";
-- reg : physical base address and the size of the registers window
-- gpio-controller : specifies that the node is a GPIO controller
-- #gpio-cells : size of the GPIO specifier, should be 2:
- - first cell is the pseudo-GPIO line number:
- 0 - MMC CARDIN
- 1 - MMC WPROT
- 2 - NOR FLASH WPn
- - second cell can take standard GPIO flags (currently ignored).
-
-Example:
- v2m_sysreg: sysreg@10000000 {
- compatible = "arm,vexpress-sysreg";
- reg = <0x10000000 0x1000>;
- gpio-controller;
- #gpio-cells = <2>;
- };
-
-This block also can also act a bridge to the platform's configuration
-bus via "system control" interface, addressing devices with site number,
-position in the board stack, config controller, function and device
-numbers - see motherboard's TRM for more details.
-
-The node describing a config device must refer to the sysreg node via
-"arm,vexpress,config-bridge" phandle (can be also defined in the node's
-parent) and relies on the board topology properties - see main vexpress
-node documentation for more details. It must must also define the
-following property:
-- arm,vexpress-sysreg,func : must contain two cells:
- - first cell defines function number (eg. 1 for clock generator,
- 2 for voltage regulators etc.)
- - device number (eg. osc 0, osc 1 etc.)
-
-Example:
- mcc {
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- };
- };
can be initialized in one of two different configurations ("memory
maps"), care must be taken to include the correct one.
-
-Root node
----------
-
Required properties in the root node:
- compatible value:
compatible = "arm,vexpress,<model>", "arm,vexpress";
- Coretile Express A9x4 (V2P-CA9) HBI-0225:
arm,hbi = <0x225>;
-
-CPU nodes
----------
-
Top-level standard "cpus" node is required. It must contain a node
with device_type = "cpu" property for every available core, eg.:
};
};
-
-Configuration infrastructure
-----------------------------
-
-The platform has an elaborated configuration system, consisting of
-microcontrollers residing on the mother- and daughterboards known
-as Motherboard/Daughterboard Configuration Controller (MCC and DCC).
-The controllers are responsible for the platform initialization
-(reset generation, flash programming, FPGA bitfiles loading etc.)
-but also control clock generators, voltage regulators, gather
-environmental data like temperature, power consumption etc. Even
-the video output switch (FPGA) is controlled that way.
-
-Nodes describing devices controlled by this infrastructure should
-point at the bridge device node:
-- bridge phandle:
- arm,vexpress,config-bridge = <phandle>;
-This property can be also defined in a parent node (eg. for a DCC)
-and is effective for all children.
-
-
-Platform topology
------------------
-
-As Versatile Express can be configured in number of physically
-different setups, the device tree should describe platform topology.
-Root node and main motherboard node must define the following
-property, describing physical location of the children nodes:
-- site number:
- arm,vexpress,site = <number>;
- where 0 means motherboard, 1 or 2 are daugtherboard sites,
- 0xf means "master" site (site containing main CPU tile)
-- when daughterboards are stacked on one site, their position
- in the stack be be described with:
- arm,vexpress,position = <number>;
-- when describing tiles consisting more than one DCC, its number
- can be described with:
- arm,vexpress,dcc = <number>;
-
-Any of the numbers above defaults to zero if not defined in
-the node or any of its parent.
-
-
-Motherboard
------------
-
The motherboard description file provides a single "motherboard" node
using 2 address cells corresponding to the Static Memory Bus used
between the motherboard and the tile. The first cell defines the Chip
- SP804 timers:
v2m_timer01 and v2m_timer23
-The tile description should define a "smb" node, describing the
-Static Memory Bus between the tile and motherboard. It must define
-the following properties:
-- "simple-bus" compatible value (to ensure creation of the children)
- compatible = "simple-bus";
-- mapping of the SMB CS/offset addresses into main address space:
- #address-cells = <2>;
- #size-cells = <1>;
- ranges = <...>;
-- interrupts mapping:
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 63>;
- interrupt-map = <...>;
+Current Linux implementation requires a "arm,v2m_timer" alias
+pointing at one of the motherboard's SP804 timers, if it is to be
+used as the system timer. This alias should be defined in the
+motherboard files.
+The tile description must define "ranges", "interrupt-map-mask" and
+"interrupt-map" properties to translate the motherboard's address
+and interrupt space into one used by the tile's processor.
-Example of a VE tile description (simplified)
----------------------------------------------
+Abbreviated example:
/dts-v1/;
/ {
model = "V2P-CA5s";
arm,hbi = <0x225>;
- arm,vexpress,site = <0xf>;
compatible = "arm,vexpress-v2p-ca5s", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <1>;
<0x2c000100 0x100>;
};
- dcc {
- compatible = "simple-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- compatible = "arm,vexpress-osc";
- };
- };
-
- smb {
- compatible = "simple-bus";
-
- #address-cells = <2>;
- #size-cells = <1>;
+ motherboard {
/* CS0 is visible at 0x08000000 */
ranges = <0 0 0x08000000 0x04000000>;
-
- #interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
/* Active high IRQ 0 is connected to GIC's SPI0 */
interrupt-map = <0 0 0 &gic 0 0 4>;
-
- /include/ "vexpress-v2m-rs1.dtsi"
};
};
+/include/ "vexpress-v2m-rs1.dtsi"
* CHANGES TO vexpress-v2m.dtsi!
*/
+/ {
+ aliases {
+ arm,v2m_timer = &v2m_timer01;
+ };
+
motherboard {
- model = "V2M-P1";
- arm,hbi = <0x190>;
- arm,vexpress,site = <0>;
+ compatible = "simple-bus";
arm,v2m-memory-map = "rs1";
- compatible = "arm,vexpress,v2m-p1", "simple-bus";
#address-cells = <2>; /* SMB chipselect number and offset */
#size-cells = <1>;
#interrupt-cells = <1>;
- ranges;
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
#size-cells = <1>;
ranges = <0 3 0 0x200000>;
- v2m_sysreg: sysreg@010000 {
+ sysreg@010000 {
compatible = "arm,vexpress-sysreg";
reg = <0x010000 0x1000>;
- gpio-controller;
- #gpio-cells = <2>;
};
- v2m_sysctl: sysctl@020000 {
+ sysctl@020000 {
compatible = "arm,sp810", "arm,primecell";
reg = <0x020000 0x1000>;
- clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
- clock-names = "refclk", "timclk", "apb_pclk";
- #clock-cells = <1>;
- clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
};
/* PCI-E I2C bus */
compatible = "arm,pl041", "arm,primecell";
reg = <0x040000 0x1000>;
interrupts = <11>;
- clocks = <&smbclk>;
- clock-names = "apb_pclk";
};
mmci@050000 {
compatible = "arm,pl180", "arm,primecell";
reg = <0x050000 0x1000>;
interrupts = <9 10>;
- cd-gpios = <&v2m_sysreg 0 0>;
- wp-gpios = <&v2m_sysreg 1 0>;
- max-frequency = <12000000>;
- vmmc-supply = <&v2m_fixed_3v3>;
- clocks = <&v2m_clk24mhz>, <&smbclk>;
- clock-names = "mclk", "apb_pclk";
};
kmi@060000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x060000 0x1000>;
interrupts = <12>;
- clocks = <&v2m_clk24mhz>, <&smbclk>;
- clock-names = "KMIREFCLK", "apb_pclk";
};
kmi@070000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x070000 0x1000>;
interrupts = <13>;
- clocks = <&v2m_clk24mhz>, <&smbclk>;
- clock-names = "KMIREFCLK", "apb_pclk";
};
v2m_serial0: uart@090000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x090000 0x1000>;
interrupts = <5>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
v2m_serial1: uart@0a0000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0a0000 0x1000>;
interrupts = <6>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
v2m_serial2: uart@0b0000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0b0000 0x1000>;
interrupts = <7>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
v2m_serial3: uart@0c0000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0c0000 0x1000>;
interrupts = <8>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
wdt@0f0000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0f0000 0x1000>;
interrupts = <0>;
- clocks = <&v2m_refclk32khz>, <&smbclk>;
- clock-names = "wdogclk", "apb_pclk";
};
v2m_timer01: timer@110000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x110000 0x1000>;
interrupts = <2>;
- clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
- clock-names = "timclken1", "timclken2", "apb_pclk";
};
v2m_timer23: timer@120000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x120000 0x1000>;
interrupts = <3>;
- clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
- clock-names = "timclken1", "timclken2", "apb_pclk";
};
/* DVI I2C bus */
compatible = "arm,pl031", "arm,primecell";
reg = <0x170000 0x1000>;
interrupts = <4>;
- clocks = <&smbclk>;
- clock-names = "apb_pclk";
};
compact-flash@1a0000 {
compatible = "arm,pl111", "arm,primecell";
reg = <0x1f0000 0x1000>;
interrupts = <14>;
- clocks = <&v2m_oscclk1>, <&smbclk>;
- clock-names = "clcdclk", "apb_pclk";
};
};
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
-
- v2m_clk24mhz: clk24mhz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <24000000>;
- clock-output-names = "v2m:clk24mhz";
- };
-
- v2m_refclk1mhz: refclk1mhz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <1000000>;
- clock-output-names = "v2m:refclk1mhz";
- };
-
- v2m_refclk32khz: refclk32khz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <32768>;
- clock-output-names = "v2m:refclk32khz";
- };
-
- mcc {
- compatible = "arm,vexpress,config-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- /* MCC static memory clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- freq-range = <25000000 60000000>;
- #clock-cells = <0>;
- clock-output-names = "v2m:oscclk0";
- };
-
- v2m_oscclk1: osc@1 {
- /* CLCD clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 1>;
- freq-range = <23750000 63500000>;
- #clock-cells = <0>;
- clock-output-names = "v2m:oscclk1";
- };
-
- v2m_oscclk2: osc@2 {
- /* IO FPGA peripheral clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 2>;
- freq-range = <24000000 24000000>;
- #clock-cells = <0>;
- clock-output-names = "v2m:oscclk2";
- };
-
- volt@0 {
- /* Logic level voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 0>;
- regulator-name = "VIO";
- regulator-always-on;
- label = "VIO";
- };
-
- temp@0 {
- /* MCC internal operating temperature */
- compatible = "arm,vexpress-temp";
- arm,vexpress-sysreg,func = <4 0>;
- label = "MCC";
- };
-
- reset@0 {
- compatible = "arm,vexpress-reset";
- arm,vexpress-sysreg,func = <5 0>;
- };
-
- muxfpga@0 {
- compatible = "arm,vexpress-muxfpga";
- arm,vexpress-sysreg,func = <7 0>;
- };
-
- shutdown@0 {
- compatible = "arm,vexpress-shutdown";
- arm,vexpress-sysreg,func = <8 0>;
- };
-
- reboot@0 {
- compatible = "arm,vexpress-reboot";
- arm,vexpress-sysreg,func = <9 0>;
- };
-
- dvimode@0 {
- compatible = "arm,vexpress-dvimode";
- arm,vexpress-sysreg,func = <11 0>;
- };
- };
};
+};
* CHANGES TO vexpress-v2m-rs1.dtsi!
*/
+/ {
+ aliases {
+ arm,v2m_timer = &v2m_timer01;
+ };
+
motherboard {
- model = "V2M-P1";
- arm,hbi = <0x190>;
- arm,vexpress,site = <0>;
- compatible = "arm,vexpress,v2m-p1", "simple-bus";
+ compatible = "simple-bus";
#address-cells = <2>; /* SMB chipselect number and offset */
#size-cells = <1>;
#interrupt-cells = <1>;
- ranges;
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
#size-cells = <1>;
ranges = <0 7 0 0x20000>;
- v2m_sysreg: sysreg@00000 {
+ sysreg@00000 {
compatible = "arm,vexpress-sysreg";
reg = <0x00000 0x1000>;
- gpio-controller;
- #gpio-cells = <2>;
};
- v2m_sysctl: sysctl@01000 {
+ sysctl@01000 {
compatible = "arm,sp810", "arm,primecell";
reg = <0x01000 0x1000>;
- clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
- clock-names = "refclk", "timclk", "apb_pclk";
- #clock-cells = <1>;
- clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
};
/* PCI-E I2C bus */
compatible = "arm,pl041", "arm,primecell";
reg = <0x04000 0x1000>;
interrupts = <11>;
- clocks = <&smbclk>;
- clock-names = "apb_pclk";
};
mmci@05000 {
compatible = "arm,pl180", "arm,primecell";
reg = <0x05000 0x1000>;
interrupts = <9 10>;
- cd-gpios = <&v2m_sysreg 0 0>;
- wp-gpios = <&v2m_sysreg 1 0>;
- max-frequency = <12000000>;
- vmmc-supply = <&v2m_fixed_3v3>;
- clocks = <&v2m_clk24mhz>, <&smbclk>;
- clock-names = "mclk", "apb_pclk";
};
kmi@06000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x06000 0x1000>;
interrupts = <12>;
- clocks = <&v2m_clk24mhz>, <&smbclk>;
- clock-names = "KMIREFCLK", "apb_pclk";
};
kmi@07000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x07000 0x1000>;
interrupts = <13>;
- clocks = <&v2m_clk24mhz>, <&smbclk>;
- clock-names = "KMIREFCLK", "apb_pclk";
};
v2m_serial0: uart@09000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x09000 0x1000>;
interrupts = <5>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
v2m_serial1: uart@0a000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0a000 0x1000>;
interrupts = <6>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
v2m_serial2: uart@0b000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0b000 0x1000>;
interrupts = <7>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
v2m_serial3: uart@0c000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0c000 0x1000>;
interrupts = <8>;
- clocks = <&v2m_oscclk2>, <&smbclk>;
- clock-names = "uartclk", "apb_pclk";
};
wdt@0f000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0f000 0x1000>;
interrupts = <0>;
- clocks = <&v2m_refclk32khz>, <&smbclk>;
- clock-names = "wdogclk", "apb_pclk";
};
v2m_timer01: timer@11000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x11000 0x1000>;
interrupts = <2>;
- clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
- clock-names = "timclken1", "timclken2", "apb_pclk";
};
v2m_timer23: timer@12000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x12000 0x1000>;
interrupts = <3>;
- clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
- clock-names = "timclken1", "timclken2", "apb_pclk";
};
/* DVI I2C bus */
compatible = "arm,pl031", "arm,primecell";
reg = <0x17000 0x1000>;
interrupts = <4>;
- clocks = <&smbclk>;
- clock-names = "apb_pclk";
};
compact-flash@1a000 {
compatible = "arm,pl111", "arm,primecell";
reg = <0x1f000 0x1000>;
interrupts = <14>;
- clocks = <&v2m_oscclk1>, <&smbclk>;
- clock-names = "clcdclk", "apb_pclk";
};
};
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
-
- v2m_clk24mhz: clk24mhz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <24000000>;
- clock-output-names = "v2m:clk24mhz";
- };
-
- v2m_refclk1mhz: refclk1mhz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <1000000>;
- clock-output-names = "v2m:refclk1mhz";
- };
-
- v2m_refclk32khz: refclk32khz {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <32768>;
- clock-output-names = "v2m:refclk32khz";
- };
-
- mcc {
- compatible = "arm,vexpress,config-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- /* MCC static memory clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- freq-range = <25000000 60000000>;
- #clock-cells = <0>;
- clock-output-names = "v2m:oscclk0";
- };
-
- v2m_oscclk1: osc@1 {
- /* CLCD clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 1>;
- freq-range = <23750000 63500000>;
- #clock-cells = <0>;
- clock-output-names = "v2m:oscclk1";
- };
-
- v2m_oscclk2: osc@2 {
- /* IO FPGA peripheral clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 2>;
- freq-range = <24000000 24000000>;
- #clock-cells = <0>;
- clock-output-names = "v2m:oscclk2";
- };
-
- volt@0 {
- /* Logic level voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 0>;
- regulator-name = "VIO";
- regulator-always-on;
- label = "VIO";
- };
-
- temp@0 {
- /* MCC internal operating temperature */
- compatible = "arm,vexpress-temp";
- arm,vexpress-sysreg,func = <4 0>;
- label = "MCC";
- };
-
- reset@0 {
- compatible = "arm,vexpress-reset";
- arm,vexpress-sysreg,func = <5 0>;
- };
-
- muxfpga@0 {
- compatible = "arm,vexpress-muxfpga";
- arm,vexpress-sysreg,func = <7 0>;
- };
-
- shutdown@0 {
- compatible = "arm,vexpress-shutdown";
- arm,vexpress-sysreg,func = <8 0>;
- };
-
- reboot@0 {
- compatible = "arm,vexpress-reboot";
- arm,vexpress-sysreg,func = <9 0>;
- };
-
- dvimode@0 {
- compatible = "arm,vexpress-dvimode";
- arm,vexpress-sysreg,func = <11 0>;
- };
- };
};
+};
/ {
model = "V2P-CA15";
arm,hbi = <0x237>;
- arm,vexpress,site = <0xf>;
compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <2>;
compatible = "arm,hdlcd";
reg = <0 0x2b000000 0 0x1000>;
interrupts = <0 85 4>;
- clocks = <&oscclk5>;
- clock-names = "pxlclk";
};
memory-controller@2b0a0000 {
compatible = "arm,pl341", "arm,primecell";
reg = <0 0x2b0a0000 0 0x1000>;
- clocks = <&oscclk7>;
- clock-names = "apb_pclk";
};
wdt@2b060000 {
compatible = "arm,sp805", "arm,primecell";
- status = "disabled";
reg = <0 0x2b060000 0 0x1000>;
interrupts = <98>;
- clocks = <&oscclk7>;
- clock-names = "apb_pclk";
};
gic: interrupt-controller@2c001000 {
reg = <0 0x7ffd0000 0 0x1000>;
interrupts = <0 86 4>,
<0 87 4>;
- clocks = <&oscclk7>;
- clock-names = "apb_pclk";
};
dma@7ffb0000 {
<0 89 4>,
<0 90 4>,
<0 91 4>;
- clocks = <&oscclk7>;
- clock-names = "apb_pclk";
};
timer {
<0 69 4>;
};
- dcc {
- compatible = "arm,vexpress,config-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- /* CPU PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- freq-range = <50000000 60000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk0";
- };
-
- osc@4 {
- /* Multiplexed AXI master clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 4>;
- freq-range = <20000000 40000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk4";
- };
-
- oscclk5: osc@5 {
- /* HDLCD PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 5>;
- freq-range = <23750000 165000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk5";
- };
-
- smbclk: osc@6 {
- /* SMB clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 6>;
- freq-range = <20000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk6";
- };
-
- oscclk7: osc@7 {
- /* SYS PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 7>;
- freq-range = <20000000 60000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk7";
- };
-
- osc@8 {
- /* DDR2 PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 8>;
- freq-range = <40000000 40000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk8";
- };
-
- volt@0 {
- /* CPU core voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 0>;
- regulator-name = "Cores";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1050000>;
- regulator-always-on;
- label = "Cores";
- };
-
- amp@0 {
- /* Total current for the two cores */
- compatible = "arm,vexpress-amp";
- arm,vexpress-sysreg,func = <3 0>;
- label = "Cores";
- };
-
- temp@0 {
- /* DCC internal temperature */
- compatible = "arm,vexpress-temp";
- arm,vexpress-sysreg,func = <4 0>;
- label = "DCC";
- };
-
- power@0 {
- /* Total power */
- compatible = "arm,vexpress-power";
- arm,vexpress-sysreg,func = <12 0>;
- label = "Cores";
- };
-
- energy@0 {
- /* Total energy */
- compatible = "arm,vexpress-energy";
- arm,vexpress-sysreg,func = <13 0>;
- label = "Cores";
- };
- };
-
- smb {
- compatible = "simple-bus";
-
- #address-cells = <2>;
- #size-cells = <1>;
+ motherboard {
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
- #interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 4>,
<0 0 1 &gic 0 1 4>,
<0 0 40 &gic 0 40 4>,
<0 0 41 &gic 0 41 4>,
<0 0 42 &gic 0 42 4>;
-
- /include/ "vexpress-v2m-rs1.dtsi"
};
};
+
+/include/ "vexpress-v2m-rs1.dtsi"
/ {
model = "V2P-CA15_CA7";
arm,hbi = <0x249>;
- arm,vexpress,site = <0xf>;
compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <2>;
compatible = "arm,sp805", "arm,primecell";
reg = <0 0x2a490000 0 0x1000>;
interrupts = <98>;
- clocks = <&oscclk6a>, <&oscclk6a>;
- clock-names = "wdogclk", "apb_pclk";
};
hdlcd@2b000000 {
compatible = "arm,hdlcd";
reg = <0 0x2b000000 0 0x1000>;
interrupts = <0 85 4>;
- clocks = <&oscclk5>;
- clock-names = "pxlclk";
};
memory-controller@2b0a0000 {
compatible = "arm,pl341", "arm,primecell";
reg = <0 0x2b0a0000 0 0x1000>;
- clocks = <&oscclk6a>;
- clock-names = "apb_pclk";
};
gic: interrupt-controller@2c001000 {
reg = <0 0x7ffd0000 0 0x1000>;
interrupts = <0 86 4>,
<0 87 4>;
- clocks = <&oscclk6a>;
- clock-names = "apb_pclk";
};
dma@7ff00000 {
<0 89 4>,
<0 90 4>,
<0 91 4>;
- clocks = <&oscclk6a>;
- clock-names = "apb_pclk";
};
timer {
<0 69 4>;
};
- oscclk6a: oscclk6a {
- /* Reference 24MHz clock */
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <24000000>;
- clock-output-names = "oscclk6a";
- };
-
- dcc {
- compatible = "arm,vexpress,config-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- /* A15 PLL 0 reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- freq-range = <17000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk0";
- };
-
- osc@1 {
- /* A15 PLL 1 reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 1>;
- freq-range = <17000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk1";
- };
-
- osc@2 {
- /* A7 PLL 0 reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 2>;
- freq-range = <17000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk2";
- };
-
- osc@3 {
- /* A7 PLL 1 reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 3>;
- freq-range = <17000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk3";
- };
-
- osc@4 {
- /* External AXI master clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 4>;
- freq-range = <20000000 40000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk4";
- };
-
- oscclk5: osc@5 {
- /* HDLCD PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 5>;
- freq-range = <23750000 165000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk5";
- };
-
- smbclk: osc@6 {
- /* Static memory controller clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 6>;
- freq-range = <20000000 40000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk6";
- };
-
- osc@7 {
- /* SYS PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 7>;
- freq-range = <17000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk7";
- };
-
- osc@8 {
- /* DDR2 PLL reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 8>;
- freq-range = <20000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk8";
- };
-
- volt@0 {
- /* A15 CPU core voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 0>;
- regulator-name = "A15 Vcore";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1050000>;
- regulator-always-on;
- label = "A15 Vcore";
- };
-
- volt@1 {
- /* A7 CPU core voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 1>;
- regulator-name = "A7 Vcore";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1050000>;
- regulator-always-on;
- label = "A7 Vcore";
- };
-
- amp@0 {
- /* Total current for the two A15 cores */
- compatible = "arm,vexpress-amp";
- arm,vexpress-sysreg,func = <3 0>;
- label = "A15 Icore";
- };
-
- amp@1 {
- /* Total current for the three A7 cores */
- compatible = "arm,vexpress-amp";
- arm,vexpress-sysreg,func = <3 1>;
- label = "A7 Icore";
- };
-
- temp@0 {
- /* DCC internal temperature */
- compatible = "arm,vexpress-temp";
- arm,vexpress-sysreg,func = <4 0>;
- label = "DCC";
- };
-
- power@0 {
- /* Total power for the two A15 cores */
- compatible = "arm,vexpress-power";
- arm,vexpress-sysreg,func = <12 0>;
- label = "A15 Pcore";
- };
- power@1 {
- /* Total power for the three A7 cores */
- compatible = "arm,vexpress-power";
- arm,vexpress-sysreg,func = <12 1>;
- label = "A7 Pcore";
- };
-
- energy@0 {
- /* Total energy for the two A15 cores */
- compatible = "arm,vexpress-energy";
- arm,vexpress-sysreg,func = <13 0>;
- label = "A15 Jcore";
- };
-
- energy@2 {
- /* Total energy for the three A7 cores */
- compatible = "arm,vexpress-energy";
- arm,vexpress-sysreg,func = <13 2>;
- label = "A7 Jcore";
- };
- };
-
- smb {
- compatible = "simple-bus";
-
- #address-cells = <2>;
- #size-cells = <1>;
+ motherboard {
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
- #interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 4>,
<0 0 1 &gic 0 1 4>,
<0 0 40 &gic 0 40 4>,
<0 0 41 &gic 0 41 4>,
<0 0 42 &gic 0 42 4>;
-
- /include/ "vexpress-v2m-rs1.dtsi"
};
};
+
+/include/ "vexpress-v2m-rs1.dtsi"
/ {
model = "V2P-CA5s";
arm,hbi = <0x225>;
- arm,vexpress,site = <0xf>;
compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <1>;
compatible = "arm,hdlcd";
reg = <0x2a110000 0x1000>;
interrupts = <0 85 4>;
- clocks = <&oscclk3>;
- clock-names = "pxlclk";
};
memory-controller@2a150000 {
compatible = "arm,pl341", "arm,primecell";
reg = <0x2a150000 0x1000>;
- clocks = <&oscclk1>;
- clock-names = "apb_pclk";
};
memory-controller@2a190000 {
reg = <0x2a190000 0x1000>;
interrupts = <0 86 4>,
<0 87 4>;
- clocks = <&oscclk1>;
- clock-names = "apb_pclk";
};
scu@2c000000 {
<0 69 4>;
};
- dcc {
- compatible = "arm,vexpress,config-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- /* CPU and internal AXI reference clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- freq-range = <50000000 100000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk0";
- };
-
- oscclk1: osc@1 {
- /* Multiplexed AXI master clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 1>;
- freq-range = <5000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk1";
- };
-
- osc@2 {
- /* DDR2 */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 2>;
- freq-range = <80000000 120000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk2";
- };
-
- oscclk3: osc@3 {
- /* HDLCD */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 3>;
- freq-range = <23750000 165000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk3";
- };
-
- osc@4 {
- /* Test chip gate configuration */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 4>;
- freq-range = <80000000 80000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk4";
- };
-
- smbclk: osc@5 {
- /* SMB clock */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 5>;
- freq-range = <25000000 60000000>;
- #clock-cells = <0>;
- clock-output-names = "oscclk5";
- };
-
- temp@0 {
- /* DCC internal operating temperature */
- compatible = "arm,vexpress-temp";
- arm,vexpress-sysreg,func = <4 0>;
- label = "DCC";
- };
- };
-
- smb {
- compatible = "simple-bus";
-
- #address-cells = <2>;
- #size-cells = <1>;
+ motherboard {
ranges = <0 0 0x08000000 0x04000000>,
<1 0 0x14000000 0x04000000>,
<2 0 0x18000000 0x04000000>,
<4 0 0x0c000000 0x04000000>,
<5 0 0x10000000 0x04000000>;
- #interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 4>,
<0 0 1 &gic 0 1 4>,
<0 0 40 &gic 0 40 4>,
<0 0 41 &gic 0 41 4>,
<0 0 42 &gic 0 42 4>;
-
- /include/ "vexpress-v2m-rs1.dtsi"
};
};
+
+/include/ "vexpress-v2m-rs1.dtsi"
/ {
model = "V2P-CA9";
arm,hbi = <0x191>;
- arm,vexpress,site = <0xf>;
compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <1>;
compatible = "arm,pl111", "arm,primecell";
reg = <0x10020000 0x1000>;
interrupts = <0 44 4>;
- clocks = <&oscclk1>, <&oscclk2>;
- clock-names = "clcdclk", "apb_pclk";
};
memory-controller@100e0000 {
compatible = "arm,pl341", "arm,primecell";
reg = <0x100e0000 0x1000>;
- clocks = <&oscclk2>;
- clock-names = "apb_pclk";
};
memory-controller@100e1000 {
reg = <0x100e1000 0x1000>;
interrupts = <0 45 4>,
<0 46 4>;
- clocks = <&oscclk2>;
- clock-names = "apb_pclk";
};
timer@100e4000 {
reg = <0x100e4000 0x1000>;
interrupts = <0 48 4>,
<0 49 4>;
- clocks = <&oscclk2>, <&oscclk2>;
- clock-names = "timclk", "apb_pclk";
};
watchdog@100e5000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x100e5000 0x1000>;
interrupts = <0 51 4>;
- clocks = <&oscclk2>, <&oscclk2>;
- clock-names = "wdogclk", "apb_pclk";
};
scu@1e000000 {
<0 63 4>;
};
- dcc {
- compatible = "arm,vexpress,config-bus";
- arm,vexpress,config-bridge = <&v2m_sysreg>;
-
- osc@0 {
- /* ACLK clock to the AXI master port on the test chip */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 0>;
- freq-range = <30000000 50000000>;
- #clock-cells = <0>;
- clock-output-names = "extsaxiclk";
- };
-
- oscclk1: osc@1 {
- /* Reference clock for the CLCD */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 1>;
- freq-range = <10000000 80000000>;
- #clock-cells = <0>;
- clock-output-names = "clcdclk";
- };
-
- smbclk: oscclk2: osc@2 {
- /* Reference clock for the test chip internal PLLs */
- compatible = "arm,vexpress-osc";
- arm,vexpress-sysreg,func = <1 2>;
- freq-range = <33000000 100000000>;
- #clock-cells = <0>;
- clock-output-names = "tcrefclk";
- };
-
- volt@0 {
- /* Test Chip internal logic voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 0>;
- regulator-name = "VD10";
- regulator-always-on;
- label = "VD10";
- };
-
- volt@1 {
- /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 1>;
- regulator-name = "VD10_S2";
- regulator-always-on;
- label = "VD10_S2";
- };
-
- volt@2 {
- /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 2>;
- regulator-name = "VD10_S3";
- regulator-always-on;
- label = "VD10_S3";
- };
-
- volt@3 {
- /* DDR2 SDRAM and Test Chip DDR2 I/O supply */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 3>;
- regulator-name = "VCC1V8";
- regulator-always-on;
- label = "VCC1V8";
- };
-
- volt@4 {
- /* DDR2 SDRAM VTT termination voltage */
- compatible = "arm,vexpress-volt";
- arm,vexpress-sysreg,func = <2 4>;
- regulator-name = "DDR2VTT";
- regulator-always-on;
- label = "DDR2VTT";
- };
-
- volt@5 {
- /* Local board supply for miscellaneous logic external to the Test Chip */
- arm,vexpress-sysreg,func = <2 5>;
- compatible = "arm,vexpress-volt";
- regulator-name = "VCC3V3";
- regulator-always-on;
- label = "VCC3V3";
- };
-
- amp@0 {
- /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
- compatible = "arm,vexpress-amp";
- arm,vexpress-sysreg,func = <3 0>;
- label = "VD10_S2";
- };
-
- amp@1 {
- /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
- compatible = "arm,vexpress-amp";
- arm,vexpress-sysreg,func = <3 1>;
- label = "VD10_S3";
- };
-
- power@0 {
- /* PL310, L2 cache, RAM cell supply (not PL310 logic) */
- compatible = "arm,vexpress-power";
- arm,vexpress-sysreg,func = <12 0>;
- label = "PVD10_S2";
- };
-
- power@1 {
- /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
- compatible = "arm,vexpress-power";
- arm,vexpress-sysreg,func = <12 1>;
- label = "PVD10_S3";
- };
- };
-
- smb {
- compatible = "simple-bus";
-
- #address-cells = <2>;
- #size-cells = <1>;
+ motherboard {
ranges = <0 0 0x40000000 0x04000000>,
<1 0 0x44000000 0x04000000>,
<2 0 0x48000000 0x04000000>,
<3 0 0x4c000000 0x04000000>,
<7 0 0x10000000 0x00020000>;
- #interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 4>,
<0 0 1 &gic 0 1 4>,
<0 0 40 &gic 0 40 4>,
<0 0 41 &gic 0 41 4>,
<0 0 42 &gic 0 42 4>;
-
- /include/ "vexpress-v2m.dtsi"
};
};
+
+/include/ "vexpress-v2m.dtsi"
#define SCPCELLID2 0xFF8
#define SCPCELLID3 0xFFC
+#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15)
+#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15)
+
+#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
+#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
+
static inline void sysctl_soft_reset(void __iomem *base)
{
/* switch to slow mode */
config ARCH_VEXPRESS
bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
- select ARCH_REQUIRE_GPIOLIB
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
select ARM_GIC
select ARM_TIMER_SP804
select CLKDEV_LOOKUP
select COMMON_CLK
- select COMMON_CLK_VERSATILE
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
select REGULATOR_FIXED_VOLTAGE if REGULATOR
- select VEXPRESS_CONFIG
help
This option enables support for systems using Cortex processor based
ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-versatile/include
-obj-y := v2m.o reset.o
+obj-y := v2m.o
obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/clkdev.h>
-#include <linux/vexpress.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h>
ca9x4_twd_init();
}
+static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
+{
+ u32 site = v2m_get_master_site();
+
+ /*
+ * Old firmware was using the "site" component of the command
+ * to control the DVI muxer (while it should be always 0 ie. MB).
+ * Newer firmware uses the data register. Keep both for compatibility.
+ */
+ v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
+ v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE(SYS_CFG_SITE_MB), 2);
+}
+
static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
{
unsigned long framesize = 1024 * 768 * 2;
.caps = CLCD_CAP_5551 | CLCD_CAP_565,
.check = clcdfb_check,
.decode = clcdfb_decode,
+ .enable = ct_ca9x4_clcd_enable,
.setup = ct_ca9x4_clcd_setup,
.mmap = versatile_clcd_mmap_dma,
.remove = versatile_clcd_remove_dma,
&gpio_device,
};
+
+static struct v2m_osc ct_osc1 = {
+ .osc = 1,
+ .rate_min = 10000000,
+ .rate_max = 80000000,
+ .rate_default = 23750000,
+};
+
static struct resource pmu_resources[] = {
[0] = {
.start = IRQ_CT_CA9X4_PMU_CPU0,
.resource = pmu_resources,
};
-static struct platform_device osc1_device = {
- .name = "vexpress-osc",
- .id = 1,
- .num_resources = 1,
- .resource = (struct resource []) {
- VEXPRESS_RES_FUNC(0xf, 1),
- },
-};
-
static void __init ct_ca9x4_init(void)
{
int i;
+ struct clk *clk;
#ifdef CONFIG_CACHE_L2X0
void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
#endif
+ ct_osc1.site = v2m_get_master_site();
+ clk = v2m_osc_register("ct:osc1", &ct_osc1);
+ clk_register_clkdev(clk, NULL, "ct:clcd");
+
for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
platform_device_register(&pmu_device);
- platform_device_register(&osc1_device);
-
- WARN_ON(clk_register_clkdev(vexpress_osc_setup(&osc1_device.dev),
- NULL, "ct:clcd"));
}
#ifdef CONFIG_SMP
#ifndef __MACH_MOTHERBOARD_H
#define __MACH_MOTHERBOARD_H
+#include <linux/clk-provider.h>
+
/*
* Physical addresses, offset from V2M_PA_CS0-3
*/
#define V2M_CF (V2M_PA_CS7 + 0x0001a000)
#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000)
+/*
+ * Offsets from SYSREGS base
+ */
+#define V2M_SYS_ID 0x000
+#define V2M_SYS_SW 0x004
+#define V2M_SYS_LED 0x008
+#define V2M_SYS_100HZ 0x024
+#define V2M_SYS_FLAGS 0x030
+#define V2M_SYS_FLAGSSET 0x030
+#define V2M_SYS_FLAGSCLR 0x034
+#define V2M_SYS_NVFLAGS 0x038
+#define V2M_SYS_NVFLAGSSET 0x038
+#define V2M_SYS_NVFLAGSCLR 0x03c
+#define V2M_SYS_MCI 0x048
+#define V2M_SYS_FLASH 0x03c
+#define V2M_SYS_CFGSW 0x058
+#define V2M_SYS_24MHZ 0x05c
+#define V2M_SYS_MISC 0x060
+#define V2M_SYS_DMA 0x064
+#define V2M_SYS_PROCID0 0x084
+#define V2M_SYS_PROCID1 0x088
+#define V2M_SYS_CFGDATA 0x0a0
+#define V2M_SYS_CFGCTRL 0x0a4
+#define V2M_SYS_CFGSTAT 0x0a8
+
/*
* Interrupts. Those in {} are for AMBA devices
#define IRQ_V2M_PCIE (32 + 17)
+/*
+ * Configuration
+ */
+#define SYS_CFG_START (1 << 31)
+#define SYS_CFG_WRITE (1 << 30)
+#define SYS_CFG_OSC (1 << 20)
+#define SYS_CFG_VOLT (2 << 20)
+#define SYS_CFG_AMP (3 << 20)
+#define SYS_CFG_TEMP (4 << 20)
+#define SYS_CFG_RESET (5 << 20)
+#define SYS_CFG_SCC (6 << 20)
+#define SYS_CFG_MUXFPGA (7 << 20)
+#define SYS_CFG_SHUTDOWN (8 << 20)
+#define SYS_CFG_REBOOT (9 << 20)
+#define SYS_CFG_DVIMODE (11 << 20)
+#define SYS_CFG_POWER (12 << 20)
+#define SYS_CFG_SITE(n) ((n) << 16)
+#define SYS_CFG_SITE_MB 0
+#define SYS_CFG_SITE_DB1 1
+#define SYS_CFG_SITE_DB2 2
+#define SYS_CFG_STACK(n) ((n) << 12)
+
+#define SYS_CFG_ERR (1 << 1)
+#define SYS_CFG_COMPLETE (1 << 0)
+
+int v2m_cfg_write(u32 devfn, u32 data);
+int v2m_cfg_read(u32 devfn, u32 *data);
+void v2m_flags_set(u32 data);
+
+/*
+ * Miscellaneous
+ */
+#define SYS_MISC_MASTERSITE (1 << 14)
+#define SYS_PROCIDx_HBI_MASK 0xfff
+
+int v2m_get_master_site(void);
+
/*
* Core tile IDs
*/
extern struct ct_desc *ct_desc;
+/*
+ * OSC clock provider
+ */
+struct v2m_osc {
+ struct clk_hw hw;
+ u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */
+ u8 stack; /* board stack position */
+ u16 osc;
+ unsigned long rate_min;
+ unsigned long rate_max;
+ unsigned long rate_default;
+};
+
+#define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw)
+
+struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc);
+
#endif
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of_fdt.h>
-#include <linux/vexpress.h>
#include <asm/smp_scu.h>
#include <asm/hardware/gic.h>
* until it receives a soft interrupt, and then the
* secondary CPU branches to this address.
*/
- vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
+ v2m_flags_set(virt_to_phys(versatile_secondary_startup));
}
struct smp_operations __initdata vexpress_smp_ops = {
#include <linux/smsc911x.h>
#include <linux/spinlock.h>
#include <linux/usb/isp1760.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
#include <linux/mtd/physmap.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
-#include <linux/vexpress.h>
#include <asm/arch_timer.h>
#include <asm/mach-types.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/timer-sp.h>
+#include <asm/hardware/sp810.h>
#include <mach/ct-ca9x4.h>
#include <mach/motherboard.h>
},
};
+static void __iomem *v2m_sysreg_base;
+
+static void __init v2m_sysctl_init(void __iomem *base)
+{
+ u32 scctrl;
+
+ if (WARN_ON(!base))
+ return;
+
+ /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
+ scctrl = readl(base + SCCTRL);
+ scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
+ scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
+ writel(scctrl, base + SCCTRL);
+}
+
static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
{
if (WARN_ON(!base || irq == NO_IRQ))
}
+static DEFINE_SPINLOCK(v2m_cfg_lock);
+
+int v2m_cfg_write(u32 devfn, u32 data)
+{
+ /* Configuration interface broken? */
+ u32 val;
+
+ printk("%s: writing %08x to %08x\n", __func__, data, devfn);
+
+ devfn |= SYS_CFG_START | SYS_CFG_WRITE;
+
+ spin_lock(&v2m_cfg_lock);
+ val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
+ writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT);
+
+ writel(data, v2m_sysreg_base + V2M_SYS_CFGDATA);
+ writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
+
+ do {
+ val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
+ } while (val == 0);
+ spin_unlock(&v2m_cfg_lock);
+
+ return !!(val & SYS_CFG_ERR);
+}
+
+int v2m_cfg_read(u32 devfn, u32 *data)
+{
+ u32 val;
+
+ devfn |= SYS_CFG_START;
+
+ spin_lock(&v2m_cfg_lock);
+ writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT);
+ writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
+
+ mb();
+
+ do {
+ cpu_relax();
+ val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
+ } while (val == 0);
+
+ *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA);
+ spin_unlock(&v2m_cfg_lock);
+
+ return !!(val & SYS_CFG_ERR);
+}
+
+void __init v2m_flags_set(u32 data)
+{
+ writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR);
+ writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
+}
+
+int v2m_get_master_site(void)
+{
+ u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
+
+ return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1;
+}
+
+
static struct resource v2m_pcie_i2c_resource = {
.start = V2M_SERIAL_BUS_PCI,
.end = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
.dev.platform_data = &v2m_usb_config,
};
+static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH);
+}
+
static struct physmap_flash_data v2m_flash_data = {
.width = 4,
+ .set_vpp = v2m_flash_set_vpp,
};
static struct resource v2m_flash_resources[] = {
.dev.platform_data = &v2m_pata_data,
};
+static unsigned int v2m_mmci_status(struct device *dev)
+{
+ return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0);
+}
+
static struct mmci_platform_data v2m_mmci_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
- .gpio_wp = VEXPRESS_GPIO_MMC_WPROT,
- .gpio_cd = VEXPRESS_GPIO_MMC_CARDIN,
-};
-
-static struct resource v2m_sysreg_resources[] = {
- {
- .start = V2M_SYSREGS,
- .end = V2M_SYSREGS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device v2m_sysreg_device = {
- .name = "vexpress-sysreg",
- .id = -1,
- .resource = v2m_sysreg_resources,
- .num_resources = ARRAY_SIZE(v2m_sysreg_resources),
-};
-
-static struct platform_device v2m_muxfpga_device = {
- .name = "vexpress-muxfpga",
- .id = 0,
- .num_resources = 1,
- .resource = (struct resource []) {
- VEXPRESS_RES_FUNC(0, 7),
- }
-};
-
-static struct platform_device v2m_shutdown_device = {
- .name = "vexpress-shutdown",
- .id = 0,
- .num_resources = 1,
- .resource = (struct resource []) {
- VEXPRESS_RES_FUNC(0, 8),
- }
-};
-
-static struct platform_device v2m_reboot_device = {
- .name = "vexpress-reboot",
- .id = 0,
- .num_resources = 1,
- .resource = (struct resource []) {
- VEXPRESS_RES_FUNC(0, 9),
- }
-};
-
-static struct platform_device v2m_dvimode_device = {
- .name = "vexpress-dvimode",
- .id = 0,
- .num_resources = 1,
- .resource = (struct resource []) {
- VEXPRESS_RES_FUNC(0, 11),
- }
+ .status = v2m_mmci_status,
};
static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL);
&rtc_device,
};
+
+static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct v2m_osc *osc = to_v2m_osc(hw);
+
+ return !parent_rate ? osc->rate_default : parent_rate;
+}
+
+static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct v2m_osc *osc = to_v2m_osc(hw);
+
+ if (WARN_ON(rate < osc->rate_min))
+ rate = osc->rate_min;
+
+ if (WARN_ON(rate > osc->rate_max))
+ rate = osc->rate_max;
+
+ return rate;
+}
+
+static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct v2m_osc *osc = to_v2m_osc(hw);
+
+ v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) |
+ SYS_CFG_STACK(osc->stack) | osc->osc, rate);
+
+ return 0;
+}
+
+static struct clk_ops v2m_osc_ops = {
+ .recalc_rate = v2m_osc_recalc_rate,
+ .round_rate = v2m_osc_round_rate,
+ .set_rate = v2m_osc_set_rate,
+};
+
+struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc)
+{
+ struct clk_init_data init;
+
+ WARN_ON(osc->site > 2);
+ WARN_ON(osc->stack > 15);
+ WARN_ON(osc->osc > 4095);
+
+ init.name = name;
+ init.ops = &v2m_osc_ops;
+ init.flags = CLK_IS_ROOT;
+ init.num_parents = 0;
+
+ osc->hw.init = &init;
+
+ return clk_register(NULL, &osc->hw);
+}
+
+static struct v2m_osc v2m_mb_osc1 = {
+ .site = SYS_CFG_SITE_MB,
+ .osc = 1,
+ .rate_min = 23750000,
+ .rate_max = 63500000,
+ .rate_default = 23750000,
+};
+
+static const char *v2m_ref_clk_periphs[] __initconst = {
+ "mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */
+};
+
+static const char *v2m_osc1_periphs[] __initconst = {
+ "mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */
+};
+
+static const char *v2m_osc2_periphs[] __initconst = {
+ "mb:mmci", "10005000.mmci", "1c050000.mmci", /* PL180 MMCI */
+ "mb:kmi0", "10006000.kmi", "1c060000.kmi", /* PL050 KMI0 */
+ "mb:kmi1", "10007000.kmi", "1c070000.kmi", /* PL050 KMI1 */
+ "mb:uart0", "10009000.uart", "1c090000.uart", /* PL011 UART0 */
+ "mb:uart1", "1000a000.uart", "1c0a0000.uart", /* PL011 UART1 */
+ "mb:uart2", "1000b000.uart", "1c0b0000.uart", /* PL011 UART2 */
+ "mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */
+};
+
+static void __init v2m_clk_init(void)
+{
+ struct clk *clk;
+ int i;
+
+ clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
+ CLK_IS_ROOT, 0);
+ WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL));
+
+ clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL,
+ CLK_IS_ROOT, 32768);
+ for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i]));
+
+ clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL,
+ CLK_IS_ROOT, 1000000);
+ WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804"));
+ WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804"));
+
+ clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
+ for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
+
+ clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
+ CLK_IS_ROOT, 24000000);
+ for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
+}
+
static void __init v2m_timer_init(void)
{
- vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K));
+ v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
+ v2m_clk_init();
v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
}
{
if (ct_desc->init_early)
ct_desc->init_early();
- versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
+ versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
+}
+
+static void v2m_power_off(void)
+{
+ if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
+ printk(KERN_EMERG "Unable to shutdown\n");
+}
+
+static void v2m_restart(char str, const char *cmd)
+{
+ if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
+ printk(KERN_EMERG "Unable to reboot\n");
}
struct ct_desc *ct_desc;
u32 current_tile_id;
ct_desc = NULL;
- current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER)
+ current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0)
& V2M_CT_ID_MASK;
for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
static void __init v2m_map_io(void)
{
iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
- vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K));
+ v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K);
v2m_populate_ct_desc();
ct_desc->map_io();
}
regulator_register_fixed(0, v2m_eth_supplies,
ARRAY_SIZE(v2m_eth_supplies));
- platform_device_register(&v2m_muxfpga_device);
- platform_device_register(&v2m_shutdown_device);
- platform_device_register(&v2m_reboot_device);
- platform_device_register(&v2m_dvimode_device);
-
- platform_device_register(&v2m_sysreg_device);
platform_device_register(&v2m_pcie_i2c_device);
platform_device_register(&v2m_ddc_i2c_device);
platform_device_register(&v2m_flash_device);
for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
amba_device_register(v2m_amba_devs[i], &iomem_resource);
- pm_power_off = vexpress_power_off;
+ pm_power_off = v2m_power_off;
ct_desc->init_tile();
}
.timer = &v2m_timer,
.handle_irq = gic_handle_irq,
.init_machine = v2m_init,
- .restart = vexpress_restart,
+ .restart = v2m_restart,
MACHINE_END
static struct map_desc v2m_rs1_io_desc __initdata = {
void __init v2m_dt_init_early(void)
{
+ struct device_node *node;
u32 dt_hbi;
- vexpress_sysreg_of_early_init();
+ node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg");
+ v2m_sysreg_base = of_iomap(node, 0);
+ if (WARN_ON(!v2m_sysreg_base))
+ return;
/* Confirm board type against DT property, if available */
if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
- u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER);
+ int site = v2m_get_master_site();
+ u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
+ V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
+ u32 hbi = id & SYS_PROCIDx_HBI_MASK;
if (WARN_ON(dt_hbi != hbi))
pr_warning("vexpress: DT HBI (%x) is not matching "
static void __init v2m_dt_timer_init(void)
{
- struct device_node *node = NULL;
+ struct device_node *node;
+ const char *path;
+ int err;
- vexpress_clk_of_init();
+ node = of_find_compatible_node(NULL, NULL, "arm,sp810");
+ v2m_sysctl_init(of_iomap(node, 0));
- do {
- node = of_find_compatible_node(node, NULL, "arm,sp804");
- } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
- if (node) {
- pr_info("Using SP804 '%s' as a clock & events source\n",
- node->full_name);
- v2m_sp804_init(of_iomap(node, 0),
- irq_of_parse_and_map(node, 0));
- }
+ v2m_clk_init();
+ err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
+ if (WARN_ON(err))
+ return;
+ node = of_find_node_by_path(path);
+ v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0));
if (arch_timer_of_register() != 0)
twd_local_timer_of_register();
if (arch_timer_sched_clock_init() != 0)
- versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
- 24000000);
+ versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
}
static struct sys_timer v2m_dt_timer = {
.init = v2m_dt_timer_init,
};
-static const struct of_device_id v2m_dt_bus_match[] __initconst = {
- { .compatible = "simple-bus", },
- { .compatible = "arm,amba-bus", },
- { .compatible = "arm,vexpress,config-bus", },
+static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash",
+ &v2m_flash_data),
+ OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data),
+ /* RS1 memory map */
+ OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash",
+ &v2m_flash_data),
+ OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data),
{}
};
static void __init v2m_dt_init(void)
{
l2x0_of_init(0x00400000, 0xfe0fffff);
- of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL);
- pm_power_off = vexpress_power_off;
+ of_platform_populate(NULL, of_default_bus_match_table,
+ v2m_dt_auxdata_lookup, NULL);
+ pm_power_off = v2m_power_off;
}
-static const char * const v2m_dt_match[] __initconst = {
+const static char *v2m_dt_match[] __initconst = {
"arm,vexpress",
"xen,xenvm",
NULL,
.timer = &v2m_dt_timer,
.init_machine = v2m_dt_init,
.handle_irq = gic_handle_irq,
- .restart = vexpress_restart,
+ .restart = v2m_restart,
MACHINE_END
depends on MCP_UCB1200 && INPUT
endmenu
-
-config VEXPRESS_CONFIG
- bool
- help
- Platform configuration infrastructure for the ARM Ltd.
- Versatile Express.
obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
obj-$(CONFIG_MFD_SYSCON) += syscon.o
obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
-obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Copyright (C) 2012 ARM Limited
- */
-
-#define pr_fmt(fmt) "vexpress-config: " fmt
-
-#include <linux/bitops.h>
-#include <linux/completion.h>
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/vexpress.h>
-
-
-#define VEXPRESS_CONFIG_MAX_BRIDGES 2
-
-struct vexpress_config_bridge {
- struct device_node *node;
- struct vexpress_config_bridge_info *info;
- struct list_head transactions;
- spinlock_t transactions_lock;
-} vexpress_config_bridges[VEXPRESS_CONFIG_MAX_BRIDGES];
-
-static DECLARE_BITMAP(vexpress_config_bridges_map,
- ARRAY_SIZE(vexpress_config_bridges));
-static DEFINE_MUTEX(vexpress_config_bridges_mutex);
-
-struct vexpress_config_bridge *vexpress_config_bridge_register(
- struct device_node *node,
- struct vexpress_config_bridge_info *info)
-{
- struct vexpress_config_bridge *bridge;
- int i;
-
- pr_debug("Registering bridge '%s'\n", info->name);
-
- mutex_lock(&vexpress_config_bridges_mutex);
- i = find_first_zero_bit(vexpress_config_bridges_map,
- ARRAY_SIZE(vexpress_config_bridges));
- if (i >= ARRAY_SIZE(vexpress_config_bridges)) {
- pr_err("Can't register more bridges!\n");
- mutex_unlock(&vexpress_config_bridges_mutex);
- return NULL;
- }
- __set_bit(i, vexpress_config_bridges_map);
- bridge = &vexpress_config_bridges[i];
-
- bridge->node = node;
- bridge->info = info;
- INIT_LIST_HEAD(&bridge->transactions);
- spin_lock_init(&bridge->transactions_lock);
-
- mutex_unlock(&vexpress_config_bridges_mutex);
-
- return bridge;
-}
-
-void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
-{
- struct vexpress_config_bridge __bridge = *bridge;
- int i;
-
- mutex_lock(&vexpress_config_bridges_mutex);
- for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++)
- if (&vexpress_config_bridges[i] == bridge)
- __clear_bit(i, vexpress_config_bridges_map);
- mutex_unlock(&vexpress_config_bridges_mutex);
-
- WARN_ON(!list_empty(&__bridge.transactions));
- while (!list_empty(&__bridge.transactions))
- cpu_relax();
-}
-
-
-struct vexpress_config_func {
- struct vexpress_config_bridge *bridge;
- void *func;
-};
-
-struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
- struct device_node *node)
-{
- struct device_node *bridge_node;
- struct vexpress_config_func *func;
- int i;
-
- if (WARN_ON(dev && node && dev->of_node != node))
- return NULL;
- if (dev && !node)
- node = dev->of_node;
-
- func = kzalloc(sizeof(*func), GFP_KERNEL);
- if (!func)
- return NULL;
-
- bridge_node = of_node_get(node);
- while (bridge_node) {
- const __be32 *prop = of_get_property(bridge_node,
- "arm,vexpress,config-bridge", NULL);
-
- if (prop) {
- bridge_node = of_find_node_by_phandle(
- be32_to_cpup(prop));
- break;
- }
-
- bridge_node = of_get_next_parent(bridge_node);
- }
-
- mutex_lock(&vexpress_config_bridges_mutex);
- for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) {
- struct vexpress_config_bridge *bridge =
- &vexpress_config_bridges[i];
-
- if (test_bit(i, vexpress_config_bridges_map) &&
- bridge->node == bridge_node) {
- func->bridge = bridge;
- func->func = bridge->info->func_get(dev, node);
- break;
- }
- }
- mutex_unlock(&vexpress_config_bridges_mutex);
-
- if (!func->func) {
- of_node_put(node);
- kfree(func);
- return NULL;
- }
-
- return func;
-}
-
-void vexpress_config_func_put(struct vexpress_config_func *func)
-{
- func->bridge->info->func_put(func->func);
- of_node_put(func->bridge->node);
- kfree(func);
-}
-
-
-struct vexpress_config_trans {
- struct vexpress_config_func *func;
- int offset;
- bool write;
- u32 *data;
- int status;
- struct completion completion;
- struct list_head list;
-};
-
-static void vexpress_config_dump_trans(const char *what,
- struct vexpress_config_trans *trans)
-{
- pr_debug("%s %s trans %p func 0x%p offset %d data 0x%x status %d\n",
- what, trans->write ? "write" : "read", trans,
- trans->func->func, trans->offset,
- trans->data ? *trans->data : 0, trans->status);
-}
-
-static int vexpress_config_schedule(struct vexpress_config_trans *trans)
-{
- int status;
- struct vexpress_config_bridge *bridge = trans->func->bridge;
- unsigned long flags;
-
- init_completion(&trans->completion);
- trans->status = -EFAULT;
-
- spin_lock_irqsave(&bridge->transactions_lock, flags);
-
- vexpress_config_dump_trans("Executing", trans);
-
- if (list_empty(&bridge->transactions))
- status = bridge->info->func_exec(trans->func->func,
- trans->offset, trans->write, trans->data);
- else
- status = VEXPRESS_CONFIG_STATUS_WAIT;
-
- switch (status) {
- case VEXPRESS_CONFIG_STATUS_DONE:
- vexpress_config_dump_trans("Finished", trans);
- trans->status = status;
- break;
- case VEXPRESS_CONFIG_STATUS_WAIT:
- list_add_tail(&trans->list, &bridge->transactions);
- break;
- }
-
- spin_unlock_irqrestore(&bridge->transactions_lock, flags);
-
- return status;
-}
-
-void vexpress_config_complete(struct vexpress_config_bridge *bridge,
- int status)
-{
- struct vexpress_config_trans *trans;
- unsigned long flags;
-
- spin_lock_irqsave(&bridge->transactions_lock, flags);
-
- trans = list_first_entry(&bridge->transactions,
- struct vexpress_config_trans, list);
- vexpress_config_dump_trans("Completed", trans);
-
- trans->status = status;
- list_del(&trans->list);
-
- if (!list_empty(&bridge->transactions)) {
- vexpress_config_dump_trans("Pending", trans);
-
- bridge->info->func_exec(trans->func->func, trans->offset,
- trans->write, trans->data);
- }
- spin_unlock_irqrestore(&bridge->transactions_lock, flags);
-
- complete(&trans->completion);
-}
-
-int vexpress_config_wait(struct vexpress_config_trans *trans)
-{
- wait_for_completion(&trans->completion);
-
- return trans->status;
-}
-
-
-int vexpress_config_read(struct vexpress_config_func *func, int offset,
- u32 *data)
-{
- struct vexpress_config_trans trans = {
- .func = func,
- .offset = offset,
- .write = false,
- .data = data,
- .status = 0,
- };
- int status = vexpress_config_schedule(&trans);
-
- if (status == VEXPRESS_CONFIG_STATUS_WAIT)
- status = vexpress_config_wait(&trans);
-
- return status;
-}
-EXPORT_SYMBOL(vexpress_config_read);
-
-int vexpress_config_write(struct vexpress_config_func *func, int offset,
- u32 data)
-{
- struct vexpress_config_trans trans = {
- .func = func,
- .offset = offset,
- .write = true,
- .data = &data,
- .status = 0,
- };
- int status = vexpress_config_schedule(&trans);
-
- if (status == VEXPRESS_CONFIG_STATUS_WAIT)
- status = vexpress_config_wait(&trans);
-
- return status;
-}
-EXPORT_SYMBOL(vexpress_config_write);
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Copyright (C) 2012 ARM Limited
- */
-
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/timer.h>
-#include <linux/vexpress.h>
-
-#define SYS_ID 0x000
-#define SYS_SW 0x004
-#define SYS_LED 0x008
-#define SYS_100HZ 0x024
-#define SYS_FLAGS 0x030
-#define SYS_FLAGSSET 0x030
-#define SYS_FLAGSCLR 0x034
-#define SYS_NVFLAGS 0x038
-#define SYS_NVFLAGSSET 0x038
-#define SYS_NVFLAGSCLR 0x03c
-#define SYS_MCI 0x048
-#define SYS_FLASH 0x04c
-#define SYS_CFGSW 0x058
-#define SYS_24MHZ 0x05c
-#define SYS_MISC 0x060
-#define SYS_DMA 0x064
-#define SYS_PROCID0 0x084
-#define SYS_PROCID1 0x088
-#define SYS_CFGDATA 0x0a0
-#define SYS_CFGCTRL 0x0a4
-#define SYS_CFGSTAT 0x0a8
-
-#define SYS_HBI_MASK 0xfff
-#define SYS_ID_HBI_SHIFT 16
-#define SYS_PROCIDx_HBI_SHIFT 0
-
-#define SYS_MCI_CARDIN (1 << 0)
-#define SYS_MCI_WPROT (1 << 1)
-
-#define SYS_FLASH_WPn (1 << 0)
-
-#define SYS_MISC_MASTERSITE (1 << 14)
-
-#define SYS_CFGCTRL_START (1 << 31)
-#define SYS_CFGCTRL_WRITE (1 << 30)
-#define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26)
-#define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
-#define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16)
-#define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12)
-#define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0)
-
-#define SYS_CFGSTAT_ERR (1 << 1)
-#define SYS_CFGSTAT_COMPLETE (1 << 0)
-
-
-static void __iomem *vexpress_sysreg_base;
-static struct device *vexpress_sysreg_dev;
-static int vexpress_master_site;
-
-
-void vexpress_flags_set(u32 data)
-{
- writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR);
- writel(data, vexpress_sysreg_base + SYS_FLAGSSET);
-}
-
-u32 vexpress_get_procid(int site)
-{
- if (site == VEXPRESS_SITE_MASTER)
- site = vexpress_master_site;
-
- return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ?
- SYS_PROCID0 : SYS_PROCID1));
-}
-
-u32 vexpress_get_hbi(int site)
-{
- u32 id;
-
- switch (site) {
- case VEXPRESS_SITE_MB:
- id = readl(vexpress_sysreg_base + SYS_ID);
- return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK;
- case VEXPRESS_SITE_MASTER:
- case VEXPRESS_SITE_DB1:
- case VEXPRESS_SITE_DB2:
- id = vexpress_get_procid(site);
- return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
- }
-
- return ~0;
-}
-
-void __iomem *vexpress_get_24mhz_clock_base(void)
-{
- return vexpress_sysreg_base + SYS_24MHZ;
-}
-
-
-static void vexpress_sysreg_find_prop(struct device_node *node,
- const char *name, u32 *val)
-{
- of_node_get(node);
- while (node) {
- if (of_property_read_u32(node, name, val) == 0) {
- of_node_put(node);
- return;
- }
- node = of_get_next_parent(node);
- }
-}
-
-unsigned __vexpress_get_site(struct device *dev, struct device_node *node)
-{
- u32 site = 0;
-
- WARN_ON(dev && node && dev->of_node != node);
- if (dev && !node)
- node = dev->of_node;
-
- if (node) {
- vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
- } else if (dev && dev->bus == &platform_bus_type) {
- struct platform_device *pdev = to_platform_device(dev);
-
- if (pdev->num_resources == 1 &&
- pdev->resource[0].flags == IORESOURCE_BUS)
- site = pdev->resource[0].start;
- } else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) {
- site = VEXPRESS_SITE_MASTER;
- }
-
- if (site == VEXPRESS_SITE_MASTER)
- site = vexpress_master_site;
-
- return site;
-}
-
-
-struct vexpress_sysreg_config_func {
- u32 template;
- u32 device;
-};
-
-static struct vexpress_config_bridge *vexpress_sysreg_config_bridge;
-static struct timer_list vexpress_sysreg_config_timer;
-static u32 *vexpress_sysreg_config_data;
-static int vexpress_sysreg_config_tries;
-
-static void *vexpress_sysreg_config_func_get(struct device *dev,
- struct device_node *node)
-{
- struct vexpress_sysreg_config_func *config_func;
- u32 site;
- u32 position = 0;
- u32 dcc = 0;
- u32 func_device[2];
- int err = -EFAULT;
-
- if (node) {
- of_node_get(node);
- vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
- vexpress_sysreg_find_prop(node, "arm,vexpress,position",
- &position);
- vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc);
- err = of_property_read_u32_array(node,
- "arm,vexpress-sysreg,func", func_device,
- ARRAY_SIZE(func_device));
- of_node_put(node);
- } else if (dev && dev->bus == &platform_bus_type) {
- struct platform_device *pdev = to_platform_device(dev);
-
- if (pdev->num_resources == 1 &&
- pdev->resource[0].flags == IORESOURCE_BUS) {
- site = pdev->resource[0].start;
- func_device[0] = pdev->resource[0].end;
- func_device[1] = pdev->id;
- err = 0;
- }
- }
- if (err)
- return NULL;
-
- config_func = kzalloc(sizeof(*config_func), GFP_KERNEL);
- if (!config_func)
- return NULL;
-
- config_func->template = SYS_CFGCTRL_DCC(dcc);
- config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]);
- config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ?
- vexpress_master_site : site);
- config_func->template |= SYS_CFGCTRL_POSITION(position);
- config_func->device |= func_device[1];
-
- dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func,
- config_func->template, config_func->device);
-
- return config_func;
-}
-
-static void vexpress_sysreg_config_func_put(void *func)
-{
- kfree(func);
-}
-
-static int vexpress_sysreg_config_func_exec(void *func, int offset,
- bool write, u32 *data)
-{
- int status;
- struct vexpress_sysreg_config_func *config_func = func;
- u32 command;
-
- if (WARN_ON(!vexpress_sysreg_base))
- return -ENOENT;
-
- command = readl(vexpress_sysreg_base + SYS_CFGCTRL);
- if (WARN_ON(command & SYS_CFGCTRL_START))
- return -EBUSY;
-
- command = SYS_CFGCTRL_START;
- command |= write ? SYS_CFGCTRL_WRITE : 0;
- command |= config_func->template;
- command |= SYS_CFGCTRL_DEVICE(config_func->device + offset);
-
- /* Use a canary for reads */
- if (!write)
- *data = 0xdeadbeef;
-
- dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n",
- command, *data);
- writel(*data, vexpress_sysreg_base + SYS_CFGDATA);
- writel(0, vexpress_sysreg_base + SYS_CFGSTAT);
- writel(command, vexpress_sysreg_base + SYS_CFGCTRL);
- mb();
-
- if (vexpress_sysreg_dev) {
- /* Schedule completion check */
- if (!write)
- vexpress_sysreg_config_data = data;
- vexpress_sysreg_config_tries = 100;
- mod_timer(&vexpress_sysreg_config_timer,
- jiffies + usecs_to_jiffies(100));
- status = VEXPRESS_CONFIG_STATUS_WAIT;
- } else {
- /* Early execution, no timer available, have to spin */
- u32 cfgstat;
-
- do {
- cpu_relax();
- cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
- } while (!cfgstat);
-
- if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE))
- *data = readl(vexpress_sysreg_base + SYS_CFGDATA);
- status = VEXPRESS_CONFIG_STATUS_DONE;
-
- if (cfgstat & SYS_CFGSTAT_ERR)
- status = -EINVAL;
- }
-
- return status;
-}
-
-struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = {
- .name = "vexpress-sysreg",
- .func_get = vexpress_sysreg_config_func_get,
- .func_put = vexpress_sysreg_config_func_put,
- .func_exec = vexpress_sysreg_config_func_exec,
-};
-
-static void vexpress_sysreg_config_complete(unsigned long data)
-{
- int status = VEXPRESS_CONFIG_STATUS_DONE;
- u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
-
- if (cfgstat & SYS_CFGSTAT_ERR)
- status = -EINVAL;
- if (!vexpress_sysreg_config_tries--)
- status = -ETIMEDOUT;
-
- if (status < 0) {
- dev_err(vexpress_sysreg_dev, "error %d\n", status);
- } else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) {
- mod_timer(&vexpress_sysreg_config_timer,
- jiffies + usecs_to_jiffies(50));
- return;
- }
-
- if (vexpress_sysreg_config_data) {
- *vexpress_sysreg_config_data = readl(vexpress_sysreg_base +
- SYS_CFGDATA);
- dev_dbg(vexpress_sysreg_dev, "read data %x\n",
- *vexpress_sysreg_config_data);
- vexpress_sysreg_config_data = NULL;
- }
-
- vexpress_config_complete(vexpress_sysreg_config_bridge, status);
-}
-
-
-void __init vexpress_sysreg_early_init(void __iomem *base)
-{
- struct device_node *node = of_find_compatible_node(NULL, NULL,
- "arm,vexpress-sysreg");
-
- if (node)
- base = of_iomap(node, 0);
-
- if (WARN_ON(!base))
- return;
-
- vexpress_sysreg_base = base;
-
- if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE)
- vexpress_master_site = VEXPRESS_SITE_DB2;
- else
- vexpress_master_site = VEXPRESS_SITE_DB1;
-
- vexpress_sysreg_config_bridge = vexpress_config_bridge_register(
- node, &vexpress_sysreg_config_bridge_info);
- WARN_ON(!vexpress_sysreg_config_bridge);
-}
-
-void __init vexpress_sysreg_of_early_init(void)
-{
- vexpress_sysreg_early_init(NULL);
-}
-
-
-static struct vexpress_sysreg_gpio {
- unsigned long reg;
- u32 value;
-} vexpress_sysreg_gpios[] = {
- [VEXPRESS_GPIO_MMC_CARDIN] = {
- .reg = SYS_MCI,
- .value = SYS_MCI_CARDIN,
- },
- [VEXPRESS_GPIO_MMC_WPROT] = {
- .reg = SYS_MCI,
- .value = SYS_MCI_WPROT,
- },
- [VEXPRESS_GPIO_FLASH_WPn] = {
- .reg = SYS_FLASH,
- .value = SYS_FLASH_WPn,
- },
-};
-
-static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip,
- unsigned offset)
-{
- return 0;
-}
-
-static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- return 0;
-}
-
-static int vexpress_sysreg_gpio_get(struct gpio_chip *chip,
- unsigned offset)
-{
- struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
- u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
-
- return !!(reg_value & gpio->value);
-}
-
-static void vexpress_sysreg_gpio_set(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
- u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
-
- if (value)
- reg_value |= gpio->value;
- else
- reg_value &= ~gpio->value;
-
- writel(reg_value, vexpress_sysreg_base + gpio->reg);
-}
-
-static struct gpio_chip vexpress_sysreg_gpio_chip = {
- .label = "vexpress-sysreg",
- .direction_input = vexpress_sysreg_gpio_direction_input,
- .direction_output = vexpress_sysreg_gpio_direction_output,
- .get = vexpress_sysreg_gpio_get,
- .set = vexpress_sysreg_gpio_set,
- .ngpio = ARRAY_SIZE(vexpress_sysreg_gpios),
- .base = 0,
-};
-
-
-static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID));
-}
-
-DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL);
-
-static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
-{
- int err;
- struct resource *res = platform_get_resource(pdev,
- IORESOURCE_MEM, 0);
-
- if (!devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), pdev->name)) {
- dev_err(&pdev->dev, "Failed to request memory region!\n");
- return -EBUSY;
- }
-
- if (!vexpress_sysreg_base)
- vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
-
- if (!vexpress_sysreg_base) {
- dev_err(&pdev->dev, "Failed to obtain base address!\n");
- return -EFAULT;
- }
-
- setup_timer(&vexpress_sysreg_config_timer,
- vexpress_sysreg_config_complete, 0);
-
- vexpress_sysreg_gpio_chip.dev = &pdev->dev;
- err = gpiochip_add(&vexpress_sysreg_gpio_chip);
- if (err) {
- vexpress_config_bridge_unregister(
- vexpress_sysreg_config_bridge);
- dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n",
- err);
- return err;
- }
-
- vexpress_sysreg_dev = &pdev->dev;
-
- device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
-
- return 0;
-}
-
-static const struct of_device_id vexpress_sysreg_match[] = {
- { .compatible = "arm,vexpress-sysreg", },
- {},
-};
-
-static struct platform_driver vexpress_sysreg_driver = {
- .driver = {
- .name = "vexpress-sysreg",
- .of_match_table = vexpress_sysreg_match,
- },
- .probe = vexpress_sysreg_probe,
-};
-
-static int __init vexpress_sysreg_init(void)
-{
- return platform_driver_register(&vexpress_sysreg_driver);
-}
-core_initcall(vexpress_sysreg_init);
-
-
-#if defined(CONFIG_LEDS_CLASS)
-
-struct vexpress_sysreg_led {
- u32 mask;
- struct led_classdev cdev;
-} vexpress_sysreg_leds[] = {
- { .mask = 1 << 0, .cdev.name = "v2m:green:user1",
- .cdev.default_trigger = "heartbeat", },
- { .mask = 1 << 1, .cdev.name = "v2m:green:user2",
- .cdev.default_trigger = "mmc0", },
- { .mask = 1 << 2, .cdev.name = "v2m:green:user3",
- .cdev.default_trigger = "cpu0", },
- { .mask = 1 << 3, .cdev.name = "v2m:green:user4",
- .cdev.default_trigger = "cpu1", },
- { .mask = 1 << 4, .cdev.name = "v2m:green:user5",
- .cdev.default_trigger = "cpu2", },
- { .mask = 1 << 5, .cdev.name = "v2m:green:user6",
- .cdev.default_trigger = "cpu3", },
- { .mask = 1 << 6, .cdev.name = "v2m:green:user7",
- .cdev.default_trigger = "cpu4", },
- { .mask = 1 << 7, .cdev.name = "v2m:green:user8",
- .cdev.default_trigger = "cpu5", },
-};
-
-static DEFINE_SPINLOCK(vexpress_sysreg_leds_lock);
-
-static void vexpress_sysreg_led_brightness_set(struct led_classdev *cdev,
- enum led_brightness brightness)
-{
- struct vexpress_sysreg_led *led = container_of(cdev,
- struct vexpress_sysreg_led, cdev);
- unsigned long flags;
- u32 val;
-
- spin_lock_irqsave(&vexpress_sysreg_leds_lock, flags);
-
- val = readl(vexpress_sysreg_base + SYS_LED);
- if (brightness == LED_OFF)
- val &= ~led->mask;
- else
- val |= led->mask;
- writel(val, vexpress_sysreg_base + SYS_LED);
-
- spin_unlock_irqrestore(&vexpress_sysreg_leds_lock, flags);
-}
-
-static int __init vexpress_sysreg_init_leds(void)
-{
- struct vexpress_sysreg_led *led;
- int i;
-
- /* Clear all user LEDs */
- writel(0, vexpress_sysreg_base + SYS_LED);
-
- for (i = 0, led = vexpress_sysreg_leds;
- i < ARRAY_SIZE(vexpress_sysreg_leds); i++, led++) {
- int err;
-
- led->cdev.brightness_set = vexpress_sysreg_led_brightness_set;
- err = led_classdev_register(vexpress_sysreg_dev, &led->cdev);
- if (err) {
- dev_err(vexpress_sysreg_dev,
- "Failed to register LED %d! (%d)\n",
- i, err);
- while (led--, i--)
- led_classdev_unregister(&led->cdev);
- return err;
- }
- }
-
- return 0;
-}
-device_initcall(vexpress_sysreg_init_leds);
-
-#endif
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Copyright (C) 2012 ARM Limited
- */
-
-#ifndef _LINUX_VEXPRESS_H
-#define _LINUX_VEXPRESS_H
-
-#include <linux/device.h>
-
-#define VEXPRESS_SITE_MB 0
-#define VEXPRESS_SITE_DB1 1
-#define VEXPRESS_SITE_DB2 2
-#define VEXPRESS_SITE_MASTER 0xf
-
-#define VEXPRESS_CONFIG_STATUS_DONE 0
-#define VEXPRESS_CONFIG_STATUS_WAIT 1
-
-#define VEXPRESS_GPIO_MMC_CARDIN 0
-#define VEXPRESS_GPIO_MMC_WPROT 1
-#define VEXPRESS_GPIO_FLASH_WPn 2
-
-#define VEXPRESS_RES_FUNC(_site, _func) \
-{ \
- .start = (_site), \
- .end = (_func), \
- .flags = IORESOURCE_BUS, \
-}
-
-/* Config bridge API */
-
-/**
- * struct vexpress_config_bridge_info - description of the platform
- * configuration infrastructure bridge.
- *
- * @name: Bridge name
- *
- * @func_get: Obtains pointer to a configuration function for a given
- * device or a Device Tree node, to be used with @func_put
- * and @func_exec. The node pointer should take precedence
- * over device pointer when both are passed.
- *
- * @func_put: Tells the bridge that the function will not be used any
- * more, so all allocated resources can be released.
- *
- * @func_exec: Executes a configuration function read or write operation.
- * The offset selects a 32 bit word of the value accessed.
- * Must return VEXPRESS_CONFIG_STATUS_DONE when operation
- * is finished immediately, VEXPRESS_CONFIG_STATUS_WAIT when
- * will be completed in some time or negative value in case
- * of error.
- */
-struct vexpress_config_bridge_info {
- const char *name;
- void *(*func_get)(struct device *dev, struct device_node *node);
- void (*func_put)(void *func);
- int (*func_exec)(void *func, int offset, bool write, u32 *data);
-};
-
-struct vexpress_config_bridge;
-
-struct vexpress_config_bridge *vexpress_config_bridge_register(
- struct device_node *node,
- struct vexpress_config_bridge_info *info);
-void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge);
-
-void vexpress_config_complete(struct vexpress_config_bridge *bridge,
- int status);
-
-/* Config function API */
-
-struct vexpress_config_func;
-
-struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
- struct device_node *node);
-#define vexpress_config_func_get_by_dev(dev) \
- __vexpress_config_func_get(dev, NULL)
-#define vexpress_config_func_get_by_node(node) \
- __vexpress_config_func_get(NULL, node)
-void vexpress_config_func_put(struct vexpress_config_func *func);
-
-/* Both may sleep! */
-int vexpress_config_read(struct vexpress_config_func *func, int offset,
- u32 *data);
-int vexpress_config_write(struct vexpress_config_func *func, int offset,
- u32 data);
-
-/* Platform control */
-
-u32 vexpress_get_procid(int site);
-u32 vexpress_get_hbi(int site);
-void *vexpress_get_24mhz_clock_base(void);
-void vexpress_flags_set(u32 data);
-
-#define vexpress_get_site_by_node(node) __vexpress_get_site(NULL, node)
-#define vexpress_get_site_by_dev(dev) __vexpress_get_site(dev, NULL)
-unsigned __vexpress_get_site(struct device *dev, struct device_node *node);
-
-void vexpress_sysreg_early_init(void __iomem *base);
-void vexpress_sysreg_of_early_init(void);
-
-void vexpress_power_off(void);
-void vexpress_restart(char str, const char *cmd);
-
-/* Clocks */
-
-struct clk *vexpress_osc_setup(struct device *dev);
-void vexpress_osc_of_setup(struct device_node *node);
-
-void vexpress_clk_init(void __iomem *sp810_base);
-void vexpress_clk_of_init(void);
-
-#endif