mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 23:58:05 +00:00
powerpc: Remove core support for Marvell mv64x60 hostbridges
There are no longer any platforms that use Marvell's mv64x60 hostbridges so remove the supporting kernel code. CC: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Mark Greer <mgreer@animalcreek.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
297f831401
commit
04debf21fa
7 changed files with 0 additions and 1687 deletions
|
@ -1,516 +0,0 @@
|
||||||
Marvell Discovery mv64[345]6x System Controller chips
|
|
||||||
===========================================================
|
|
||||||
|
|
||||||
The Marvell mv64[345]60 series of system controller chips contain
|
|
||||||
many of the peripherals needed to implement a complete computer
|
|
||||||
system. In this section, we define device tree nodes to describe
|
|
||||||
the system controller chip itself and each of the peripherals
|
|
||||||
which it contains. Compatible string values for each node are
|
|
||||||
prefixed with the string "marvell,", for Marvell Technology Group Ltd.
|
|
||||||
|
|
||||||
1) The /system-controller node
|
|
||||||
|
|
||||||
This node is used to represent the system-controller and must be
|
|
||||||
present when the system uses a system controller chip. The top-level
|
|
||||||
system-controller node contains information that is global to all
|
|
||||||
devices within the system controller chip. The node name begins
|
|
||||||
with "system-controller" followed by the unit address, which is
|
|
||||||
the base address of the memory-mapped register set for the system
|
|
||||||
controller chip.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
|
|
||||||
- ranges : Describes the translation of system controller addresses
|
|
||||||
for memory mapped registers.
|
|
||||||
- clock-frequency: Contains the main clock frequency for the system
|
|
||||||
controller chip.
|
|
||||||
- reg : This property defines the address and size of the
|
|
||||||
memory-mapped registers contained within the system controller
|
|
||||||
chip. The address specified in the "reg" property should match
|
|
||||||
the unit address of the system-controller node.
|
|
||||||
- #address-cells : Address representation for system controller
|
|
||||||
devices. This field represents the number of cells needed to
|
|
||||||
represent the address of the memory-mapped registers of devices
|
|
||||||
within the system controller chip.
|
|
||||||
- #size-cells : Size representation for the memory-mapped
|
|
||||||
registers within the system controller chip.
|
|
||||||
- #interrupt-cells : Defines the width of cells used to represent
|
|
||||||
interrupts.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
|
|
||||||
- model : The specific model of the system controller chip. Such
|
|
||||||
as, "mv64360", "mv64460", or "mv64560".
|
|
||||||
- compatible : A string identifying the compatibility identifiers
|
|
||||||
of the system controller chip.
|
|
||||||
|
|
||||||
The system-controller node contains child nodes for each system
|
|
||||||
controller device that the platform uses. Nodes should not be created
|
|
||||||
for devices which exist on the system controller chip but are not used
|
|
||||||
|
|
||||||
Example Marvell Discovery mv64360 system-controller node:
|
|
||||||
|
|
||||||
system-controller@f1000000 { /* Marvell Discovery mv64360 */
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
model = "mv64360"; /* Default */
|
|
||||||
compatible = "marvell,mv64360";
|
|
||||||
clock-frequency = <133333333>;
|
|
||||||
reg = <0xf1000000 0x10000>;
|
|
||||||
virtual-reg = <0xf1000000>;
|
|
||||||
ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */
|
|
||||||
0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */
|
|
||||||
0xa0000000 0xa0000000 0x4000000 /* User FLASH */
|
|
||||||
0x00000000 0xf1000000 0x0010000 /* Bridge's regs */
|
|
||||||
0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */
|
|
||||||
|
|
||||||
[ child node definitions... ]
|
|
||||||
}
|
|
||||||
|
|
||||||
2) Child nodes of /system-controller
|
|
||||||
|
|
||||||
a) Marvell Discovery MDIO bus
|
|
||||||
|
|
||||||
The MDIO is a bus to which the PHY devices are connected. For each
|
|
||||||
device that exists on this bus, a child node should be created. See
|
|
||||||
the definition of the PHY node below for an example of how to define
|
|
||||||
a PHY.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- #address-cells : Should be <1>
|
|
||||||
- #size-cells : Should be <0>
|
|
||||||
- compatible : Should be "marvell,mv64360-mdio"
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
mdio {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
compatible = "marvell,mv64360-mdio";
|
|
||||||
|
|
||||||
ethernet-phy@0 {
|
|
||||||
......
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
b) Marvell Discovery ethernet controller
|
|
||||||
|
|
||||||
The Discover ethernet controller is described with two levels
|
|
||||||
of nodes. The first level describes an ethernet silicon block
|
|
||||||
and the second level describes up to 3 ethernet nodes within
|
|
||||||
that block. The reason for the multiple levels is that the
|
|
||||||
registers for the node are interleaved within a single set
|
|
||||||
of registers. The "ethernet-block" level describes the
|
|
||||||
shared register set, and the "ethernet" nodes describe ethernet
|
|
||||||
port-specific properties.
|
|
||||||
|
|
||||||
Ethernet block node
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- #address-cells : <1>
|
|
||||||
- #size-cells : <0>
|
|
||||||
- compatible : "marvell,mv64360-eth-block"
|
|
||||||
- reg : Offset and length of the register set for this block
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- clocks : Phandle to the clock control device and gate bit
|
|
||||||
|
|
||||||
Example Discovery Ethernet block node:
|
|
||||||
ethernet-block@2000 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
compatible = "marvell,mv64360-eth-block";
|
|
||||||
reg = <0x2000 0x2000>;
|
|
||||||
ethernet@0 {
|
|
||||||
.......
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Ethernet port node
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : Should be "marvell,mv64360-eth".
|
|
||||||
- reg : Should be <0>, <1>, or <2>, according to which registers
|
|
||||||
within the silicon block the device uses.
|
|
||||||
- interrupts : <a> where a is the interrupt number for the port.
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
- phy : the phandle for the PHY connected to this ethernet
|
|
||||||
controller.
|
|
||||||
- local-mac-address : 6 bytes, MAC address
|
|
||||||
|
|
||||||
Example Discovery Ethernet port node:
|
|
||||||
ethernet@0 {
|
|
||||||
compatible = "marvell,mv64360-eth";
|
|
||||||
reg = <0>;
|
|
||||||
interrupts = <32>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
phy = <&PHY0>;
|
|
||||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
c) Marvell Discovery PHY nodes
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- interrupts : <a> where a is the interrupt number for this phy.
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller that
|
|
||||||
services interrupts for this device.
|
|
||||||
- reg : The ID number for the phy, usually a small integer
|
|
||||||
|
|
||||||
Example Discovery PHY node:
|
|
||||||
ethernet-phy@1 {
|
|
||||||
compatible = "broadcom,bcm5421";
|
|
||||||
interrupts = <76>; /* GPP 12 */
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
reg = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
d) Marvell Discovery SDMA nodes
|
|
||||||
|
|
||||||
Represent DMA hardware associated with the MPSC (multiprotocol
|
|
||||||
serial controllers).
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-sdma"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupts : <a> where a is the interrupt number for the DMA
|
|
||||||
device.
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery SDMA node:
|
|
||||||
sdma@4000 {
|
|
||||||
compatible = "marvell,mv64360-sdma";
|
|
||||||
reg = <0x4000 0xc18>;
|
|
||||||
virtual-reg = <0xf1004000>;
|
|
||||||
interrupts = <36>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
e) Marvell Discovery BRG nodes
|
|
||||||
|
|
||||||
Represent baud rate generator hardware associated with the MPSC
|
|
||||||
(multiprotocol serial controllers).
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-brg"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- clock-src : A value from 0 to 15 which selects the clock
|
|
||||||
source for the baud rate generator. This value corresponds
|
|
||||||
to the CLKS value in the BRGx configuration register. See
|
|
||||||
the mv64x60 User's Manual.
|
|
||||||
- clock-frequence : The frequency (in Hz) of the baud rate
|
|
||||||
generator's input clock.
|
|
||||||
- current-speed : The current speed setting (presumably by
|
|
||||||
firmware) of the baud rate generator.
|
|
||||||
|
|
||||||
Example Discovery BRG node:
|
|
||||||
brg@b200 {
|
|
||||||
compatible = "marvell,mv64360-brg";
|
|
||||||
reg = <0xb200 0x8>;
|
|
||||||
clock-src = <8>;
|
|
||||||
clock-frequency = <133333333>;
|
|
||||||
current-speed = <9600>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
f) Marvell Discovery CUNIT nodes
|
|
||||||
|
|
||||||
Represent the Serial Communications Unit device hardware.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
|
|
||||||
Example Discovery CUNIT node:
|
|
||||||
cunit@f200 {
|
|
||||||
reg = <0xf200 0x200>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
g) Marvell Discovery MPSCROUTING nodes
|
|
||||||
|
|
||||||
Represent the Discovery's MPSC routing hardware
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
|
|
||||||
Example Discovery CUNIT node:
|
|
||||||
mpscrouting@b500 {
|
|
||||||
reg = <0xb400 0xc>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
h) Marvell Discovery MPSCINTR nodes
|
|
||||||
|
|
||||||
Represent the Discovery's MPSC DMA interrupt hardware registers
|
|
||||||
(SDMA cause and mask registers).
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
|
|
||||||
Example Discovery MPSCINTR node:
|
|
||||||
mpsintr@b800 {
|
|
||||||
reg = <0xb800 0x100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
i) Marvell Discovery MPSC nodes
|
|
||||||
|
|
||||||
Represent the Discovery's MPSC (Multiprotocol Serial Controller)
|
|
||||||
serial port.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-mpsc"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- sdma : the phandle for the SDMA node used by this port
|
|
||||||
- brg : the phandle for the BRG node used by this port
|
|
||||||
- cunit : the phandle for the CUNIT node used by this port
|
|
||||||
- mpscrouting : the phandle for the MPSCROUTING node used by this port
|
|
||||||
- mpscintr : the phandle for the MPSCINTR node used by this port
|
|
||||||
- cell-index : the hardware index of this cell in the MPSC core
|
|
||||||
- max_idle : value needed for MPSC CHR3 (Maximum Frame Length)
|
|
||||||
register
|
|
||||||
- interrupts : <a> where a is the interrupt number for the MPSC.
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery MPSCINTR node:
|
|
||||||
mpsc@8000 {
|
|
||||||
compatible = "marvell,mv64360-mpsc";
|
|
||||||
reg = <0x8000 0x38>;
|
|
||||||
virtual-reg = <0xf1008000>;
|
|
||||||
sdma = <&SDMA0>;
|
|
||||||
brg = <&BRG0>;
|
|
||||||
cunit = <&CUNIT>;
|
|
||||||
mpscrouting = <&MPSCROUTING>;
|
|
||||||
mpscintr = <&MPSCINTR>;
|
|
||||||
cell-index = <0>;
|
|
||||||
max_idle = <40>;
|
|
||||||
interrupts = <40>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
j) Marvell Discovery Watch Dog Timer nodes
|
|
||||||
|
|
||||||
Represent the Discovery's watchdog timer hardware
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-wdt"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
|
|
||||||
Example Discovery Watch Dog Timer node:
|
|
||||||
wdt@b410 {
|
|
||||||
compatible = "marvell,mv64360-wdt";
|
|
||||||
reg = <0xb410 0x8>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
k) Marvell Discovery I2C nodes
|
|
||||||
|
|
||||||
Represent the Discovery's I2C hardware
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- device_type : "i2c"
|
|
||||||
- compatible : "marvell,mv64360-i2c"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupts : <a> where a is the interrupt number for the I2C.
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery I2C node:
|
|
||||||
compatible = "marvell,mv64360-i2c";
|
|
||||||
reg = <0xc000 0x20>;
|
|
||||||
virtual-reg = <0xf100c000>;
|
|
||||||
interrupts = <37>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
|
|
||||||
|
|
||||||
Represent the Discovery's PIC hardware
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- #interrupt-cells : <1>
|
|
||||||
- #address-cells : <0>
|
|
||||||
- compatible : "marvell,mv64360-pic"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupt-controller
|
|
||||||
|
|
||||||
Example Discovery PIC node:
|
|
||||||
pic {
|
|
||||||
#interrupt-cells = <1>;
|
|
||||||
#address-cells = <0>;
|
|
||||||
compatible = "marvell,mv64360-pic";
|
|
||||||
reg = <0x0 0x88>;
|
|
||||||
interrupt-controller;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
|
|
||||||
|
|
||||||
Represent the Discovery's MPP hardware
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-mpp"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
|
|
||||||
Example Discovery MPP node:
|
|
||||||
mpp@f000 {
|
|
||||||
compatible = "marvell,mv64360-mpp";
|
|
||||||
reg = <0xf000 0x10>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
n) Marvell Discovery GPP (General Purpose Pins) nodes
|
|
||||||
|
|
||||||
Represent the Discovery's GPP hardware
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-gpp"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
|
|
||||||
Example Discovery GPP node:
|
|
||||||
gpp@f000 {
|
|
||||||
compatible = "marvell,mv64360-gpp";
|
|
||||||
reg = <0xf100 0x20>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
o) Marvell Discovery PCI host bridge node
|
|
||||||
|
|
||||||
Represents the Discovery's PCI host bridge device. The properties
|
|
||||||
for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE
|
|
||||||
1275-1994. A typical value for the compatible property is
|
|
||||||
"marvell,mv64360-pci".
|
|
||||||
|
|
||||||
Example Discovery PCI host bridge node
|
|
||||||
pci@80000000 {
|
|
||||||
#address-cells = <3>;
|
|
||||||
#size-cells = <2>;
|
|
||||||
#interrupt-cells = <1>;
|
|
||||||
device_type = "pci";
|
|
||||||
compatible = "marvell,mv64360-pci";
|
|
||||||
reg = <0xcf8 0x8>;
|
|
||||||
ranges = <0x01000000 0x0 0x0
|
|
||||||
0x88000000 0x0 0x01000000
|
|
||||||
0x02000000 0x0 0x80000000
|
|
||||||
0x80000000 0x0 0x08000000>;
|
|
||||||
bus-range = <0 255>;
|
|
||||||
clock-frequency = <66000000>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
|
||||||
interrupt-map = <
|
|
||||||
/* IDSEL 0x0a */
|
|
||||||
0x5000 0 0 1 &PIC 80
|
|
||||||
0x5000 0 0 2 &PIC 81
|
|
||||||
0x5000 0 0 3 &PIC 91
|
|
||||||
0x5000 0 0 4 &PIC 93
|
|
||||||
|
|
||||||
/* IDSEL 0x0b */
|
|
||||||
0x5800 0 0 1 &PIC 91
|
|
||||||
0x5800 0 0 2 &PIC 93
|
|
||||||
0x5800 0 0 3 &PIC 80
|
|
||||||
0x5800 0 0 4 &PIC 81
|
|
||||||
|
|
||||||
/* IDSEL 0x0c */
|
|
||||||
0x6000 0 0 1 &PIC 91
|
|
||||||
0x6000 0 0 2 &PIC 93
|
|
||||||
0x6000 0 0 3 &PIC 80
|
|
||||||
0x6000 0 0 4 &PIC 81
|
|
||||||
|
|
||||||
/* IDSEL 0x0d */
|
|
||||||
0x6800 0 0 1 &PIC 93
|
|
||||||
0x6800 0 0 2 &PIC 80
|
|
||||||
0x6800 0 0 3 &PIC 81
|
|
||||||
0x6800 0 0 4 &PIC 91
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
p) Marvell Discovery CPU Error nodes
|
|
||||||
|
|
||||||
Represent the Discovery's CPU error handler device.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-cpu-error"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupts : the interrupt number for this device
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery CPU Error node:
|
|
||||||
cpu-error@70 {
|
|
||||||
compatible = "marvell,mv64360-cpu-error";
|
|
||||||
reg = <0x70 0x10 0x128 0x28>;
|
|
||||||
interrupts = <3>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
q) Marvell Discovery SRAM Controller nodes
|
|
||||||
|
|
||||||
Represent the Discovery's SRAM controller device.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-sram-ctrl"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupts : the interrupt number for this device
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery SRAM Controller node:
|
|
||||||
sram-ctrl@380 {
|
|
||||||
compatible = "marvell,mv64360-sram-ctrl";
|
|
||||||
reg = <0x380 0x80>;
|
|
||||||
interrupts = <13>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
r) Marvell Discovery PCI Error Handler nodes
|
|
||||||
|
|
||||||
Represent the Discovery's PCI error handler device.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-pci-error"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupts : the interrupt number for this device
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery PCI Error Handler node:
|
|
||||||
pci-error@1d40 {
|
|
||||||
compatible = "marvell,mv64360-pci-error";
|
|
||||||
reg = <0x1d40 0x40 0xc28 0x4>;
|
|
||||||
interrupts = <12>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
s) Marvell Discovery Memory Controller nodes
|
|
||||||
|
|
||||||
Represent the Discovery's memory controller device.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "marvell,mv64360-mem-ctrl"
|
|
||||||
- reg : Offset and length of the register set for this device
|
|
||||||
- interrupts : the interrupt number for this device
|
|
||||||
- interrupt-parent : the phandle for the interrupt controller
|
|
||||||
that services interrupts for this device.
|
|
||||||
|
|
||||||
Example Discovery Memory Controller node:
|
|
||||||
mem-ctrl@1400 {
|
|
||||||
compatible = "marvell,mv64360-mem-ctrl";
|
|
||||||
reg = <0x1400 0x60>;
|
|
||||||
interrupts = <17>;
|
|
||||||
interrupt-parent = <&PIC>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,6 @@ obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
|
||||||
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
|
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
|
||||||
obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
|
obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
|
||||||
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
|
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
|
||||||
mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
|
|
||||||
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
|
|
||||||
mv64x60_udbg.o
|
|
||||||
obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
|
obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
|
||||||
|
|
||||||
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
|
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __MV64X60_H__
|
|
||||||
#define __MV64X60_H__
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
|
|
||||||
extern void __init mv64x60_init_irq(void);
|
|
||||||
extern unsigned int mv64x60_get_irq(void);
|
|
||||||
|
|
||||||
extern void __init mv64x60_pci_init(void);
|
|
||||||
extern void __init mv64x60_init_early(void);
|
|
||||||
|
|
||||||
#endif /* __MV64X60_H__ */
|
|
|
@ -1,535 +0,0 @@
|
||||||
/*
|
|
||||||
* Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
|
|
||||||
*
|
|
||||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
|
||||||
*
|
|
||||||
* 2007 (c) MontaVista, Software, Inc. 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/stddef.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/console.h>
|
|
||||||
#include <linux/mv643xx.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/of_platform.h>
|
|
||||||
#include <linux/of_net.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
|
|
||||||
#include <asm/prom.h>
|
|
||||||
|
|
||||||
/* These functions provide the necessary setup for the mv64x60 drivers. */
|
|
||||||
|
|
||||||
static const struct of_device_id of_mv64x60_devices[] __initconst = {
|
|
||||||
{ .compatible = "marvell,mv64306-devctrl", },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create MPSC platform devices
|
|
||||||
*/
|
|
||||||
static int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
|
|
||||||
{
|
|
||||||
struct platform_device *pdev;
|
|
||||||
struct resource r[2];
|
|
||||||
struct mpsc_shared_pdata pdata;
|
|
||||||
const phandle *ph;
|
|
||||||
struct device_node *mpscrouting, *mpscintr;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ph = of_get_property(np, "mpscrouting", NULL);
|
|
||||||
mpscrouting = of_find_node_by_phandle(*ph);
|
|
||||||
if (!mpscrouting)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
err = of_address_to_resource(mpscrouting, 0, &r[0]);
|
|
||||||
of_node_put(mpscrouting);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
ph = of_get_property(np, "mpscintr", NULL);
|
|
||||||
mpscintr = of_find_node_by_phandle(*ph);
|
|
||||||
if (!mpscintr)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
err = of_address_to_resource(mpscintr, 0, &r[1]);
|
|
||||||
of_node_put(mpscintr);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
memset(&pdata, 0, sizeof(pdata));
|
|
||||||
|
|
||||||
pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
|
|
||||||
if (!pdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
err = platform_device_add_resources(pdev, r, 2);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add(pdev);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
platform_device_put(pdev);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
|
|
||||||
{
|
|
||||||
struct resource r[5];
|
|
||||||
struct mpsc_pdata pdata;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
const unsigned int *prop;
|
|
||||||
const phandle *ph;
|
|
||||||
struct device_node *sdma, *brg;
|
|
||||||
int err;
|
|
||||||
int port_number;
|
|
||||||
|
|
||||||
/* only register the shared platform device the first time through */
|
|
||||||
if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
|
|
||||||
return err;
|
|
||||||
|
|
||||||
memset(r, 0, sizeof(r));
|
|
||||||
|
|
||||||
err = of_address_to_resource(np, 0, &r[0]);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
of_irq_to_resource(np, 0, &r[4]);
|
|
||||||
|
|
||||||
ph = of_get_property(np, "sdma", NULL);
|
|
||||||
sdma = of_find_node_by_phandle(*ph);
|
|
||||||
if (!sdma)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
of_irq_to_resource(sdma, 0, &r[3]);
|
|
||||||
err = of_address_to_resource(sdma, 0, &r[1]);
|
|
||||||
of_node_put(sdma);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
ph = of_get_property(np, "brg", NULL);
|
|
||||||
brg = of_find_node_by_phandle(*ph);
|
|
||||||
if (!brg)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
err = of_address_to_resource(brg, 0, &r[2]);
|
|
||||||
of_node_put(brg);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "cell-index", NULL);
|
|
||||||
if (!prop)
|
|
||||||
return -ENODEV;
|
|
||||||
port_number = *(int *)prop;
|
|
||||||
|
|
||||||
memset(&pdata, 0, sizeof(pdata));
|
|
||||||
|
|
||||||
pdata.cache_mgmt = 1; /* All current revs need this set */
|
|
||||||
|
|
||||||
pdata.max_idle = 40; /* default */
|
|
||||||
prop = of_get_property(np, "max_idle", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.max_idle = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(brg, "current-speed", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.default_baud = *prop;
|
|
||||||
|
|
||||||
/* Default is 8 bits, no parity, no flow control */
|
|
||||||
pdata.default_bits = 8;
|
|
||||||
pdata.default_parity = 'n';
|
|
||||||
pdata.default_flow = 'n';
|
|
||||||
|
|
||||||
prop = of_get_property(np, "chr_1", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.chr_1_val = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "chr_2", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.chr_2_val = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "chr_10", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.chr_10_val = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "mpcr", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.mpcr_val = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(brg, "bcr", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.bcr_val = *prop;
|
|
||||||
|
|
||||||
pdata.brg_can_tune = 1; /* All current revs need this set */
|
|
||||||
|
|
||||||
prop = of_get_property(brg, "clock-src", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.brg_clk_src = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(brg, "clock-frequency", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.brg_clk_freq = *prop;
|
|
||||||
|
|
||||||
pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
|
|
||||||
if (!pdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
|
||||||
|
|
||||||
err = platform_device_add_resources(pdev, r, 5);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add(pdev);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
platform_device_put(pdev);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create mv64x60_eth platform devices
|
|
||||||
*/
|
|
||||||
static struct platform_device * __init mv64x60_eth_register_shared_pdev(
|
|
||||||
struct device_node *np, int id)
|
|
||||||
{
|
|
||||||
struct platform_device *pdev;
|
|
||||||
struct resource r[2];
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = of_address_to_resource(np, 0, &r[0]);
|
|
||||||
if (err)
|
|
||||||
return ERR_PTR(err);
|
|
||||||
|
|
||||||
/* register an orion mdio bus driver */
|
|
||||||
r[1].start = r[0].start + 0x4;
|
|
||||||
r[1].end = r[0].start + 0x84 - 1;
|
|
||||||
r[1].flags = IORESOURCE_MEM;
|
|
||||||
|
|
||||||
if (id == 0) {
|
|
||||||
pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1);
|
|
||||||
if (IS_ERR(pdev))
|
|
||||||
return pdev;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
|
|
||||||
&r[0], 1);
|
|
||||||
|
|
||||||
return pdev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
|
|
||||||
struct platform_device *shared_pdev)
|
|
||||||
{
|
|
||||||
struct resource r[1];
|
|
||||||
struct mv643xx_eth_platform_data pdata;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
struct device_node *phy;
|
|
||||||
const u8 *mac_addr;
|
|
||||||
const int *prop;
|
|
||||||
const phandle *ph;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
memset(r, 0, sizeof(r));
|
|
||||||
of_irq_to_resource(np, 0, &r[0]);
|
|
||||||
|
|
||||||
memset(&pdata, 0, sizeof(pdata));
|
|
||||||
|
|
||||||
pdata.shared = shared_pdev;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "reg", NULL);
|
|
||||||
if (!prop)
|
|
||||||
return -ENODEV;
|
|
||||||
pdata.port_number = *prop;
|
|
||||||
|
|
||||||
mac_addr = of_get_mac_address(np);
|
|
||||||
if (mac_addr)
|
|
||||||
memcpy(pdata.mac_addr, mac_addr, 6);
|
|
||||||
|
|
||||||
prop = of_get_property(np, "speed", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.speed = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "tx_queue_size", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.tx_queue_size = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "rx_queue_size", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.rx_queue_size = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "tx_sram_addr", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.tx_sram_addr = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "tx_sram_size", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.tx_sram_size = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "rx_sram_addr", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.rx_sram_addr = *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "rx_sram_size", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.rx_sram_size = *prop;
|
|
||||||
|
|
||||||
ph = of_get_property(np, "phy", NULL);
|
|
||||||
if (!ph)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
phy = of_find_node_by_phandle(*ph);
|
|
||||||
if (phy == NULL)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
prop = of_get_property(phy, "reg", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.phy_addr = MV643XX_ETH_PHY_ADDR(*prop);
|
|
||||||
|
|
||||||
of_node_put(phy);
|
|
||||||
|
|
||||||
pdev = platform_device_alloc(MV643XX_ETH_NAME, id);
|
|
||||||
if (!pdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
|
||||||
err = platform_device_add_resources(pdev, r, 1);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add(pdev);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
platform_device_put(pdev);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create mv64x60_i2c platform devices
|
|
||||||
*/
|
|
||||||
static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
|
|
||||||
{
|
|
||||||
struct resource r[2];
|
|
||||||
struct platform_device *pdev;
|
|
||||||
struct mv64xxx_i2c_pdata pdata;
|
|
||||||
const unsigned int *prop;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
memset(r, 0, sizeof(r));
|
|
||||||
|
|
||||||
err = of_address_to_resource(np, 0, &r[0]);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
of_irq_to_resource(np, 0, &r[1]);
|
|
||||||
|
|
||||||
memset(&pdata, 0, sizeof(pdata));
|
|
||||||
|
|
||||||
pdata.freq_m = 8; /* default */
|
|
||||||
prop = of_get_property(np, "freq_m", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.freq_m = *prop;
|
|
||||||
|
|
||||||
pdata.freq_n = 3; /* default */
|
|
||||||
prop = of_get_property(np, "freq_n", NULL);
|
|
||||||
if (prop)
|
|
||||||
pdata.freq_n = *prop;
|
|
||||||
|
|
||||||
pdata.timeout = 1000; /* default: 1 second */
|
|
||||||
|
|
||||||
pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
|
|
||||||
if (!pdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
err = platform_device_add_resources(pdev, r, 2);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add(pdev);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
platform_device_put(pdev);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create mv64x60_wdt platform devices
|
|
||||||
*/
|
|
||||||
static int __init mv64x60_wdt_device_setup(struct device_node *np, int id)
|
|
||||||
{
|
|
||||||
struct resource r;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
struct mv64x60_wdt_pdata pdata;
|
|
||||||
const unsigned int *prop;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = of_address_to_resource(np, 0, &r);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
memset(&pdata, 0, sizeof(pdata));
|
|
||||||
|
|
||||||
pdata.timeout = 10; /* Default: 10 seconds */
|
|
||||||
|
|
||||||
np = of_get_parent(np);
|
|
||||||
if (!np)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "clock-frequency", NULL);
|
|
||||||
of_node_put(np);
|
|
||||||
if (!prop)
|
|
||||||
return -ENODEV;
|
|
||||||
pdata.bus_clk = *prop / 1000000; /* wdt driver wants freq in MHz */
|
|
||||||
|
|
||||||
pdev = platform_device_alloc(MV64x60_WDT_NAME, id);
|
|
||||||
if (!pdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
err = platform_device_add_resources(pdev, &r, 1);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = platform_device_add(pdev);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
platform_device_put(pdev);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init mv64x60_device_setup(void)
|
|
||||||
{
|
|
||||||
struct device_node *np, *np2;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
int id, id2;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
id = 0;
|
|
||||||
for_each_compatible_node(np, NULL, "marvell,mv64360-mpsc") {
|
|
||||||
err = mv64x60_mpsc_device_setup(np, id++);
|
|
||||||
if (err)
|
|
||||||
printk(KERN_ERR "Failed to initialize MV64x60 "
|
|
||||||
"serial device %pOF: error %d.\n",
|
|
||||||
np, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
id = 0;
|
|
||||||
id2 = 0;
|
|
||||||
for_each_compatible_node(np, NULL, "marvell,mv64360-eth-group") {
|
|
||||||
pdev = mv64x60_eth_register_shared_pdev(np, id++);
|
|
||||||
if (IS_ERR(pdev)) {
|
|
||||||
err = PTR_ERR(pdev);
|
|
||||||
printk(KERN_ERR "Failed to initialize MV64x60 "
|
|
||||||
"network block %pOF: error %d.\n",
|
|
||||||
np, err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for_each_child_of_node(np, np2) {
|
|
||||||
if (!of_device_is_compatible(np2,
|
|
||||||
"marvell,mv64360-eth"))
|
|
||||||
continue;
|
|
||||||
err = mv64x60_eth_device_setup(np2, id2++, pdev);
|
|
||||||
if (err)
|
|
||||||
printk(KERN_ERR "Failed to initialize "
|
|
||||||
"MV64x60 network device %pOF: "
|
|
||||||
"error %d.\n",
|
|
||||||
np2, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id = 0;
|
|
||||||
for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") {
|
|
||||||
err = mv64x60_i2c_device_setup(np, id++);
|
|
||||||
if (err)
|
|
||||||
printk(KERN_ERR "Failed to initialize MV64x60 I2C "
|
|
||||||
"bus %pOF: error %d.\n",
|
|
||||||
np, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* support up to one watchdog timer */
|
|
||||||
np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt");
|
|
||||||
if (np) {
|
|
||||||
if ((err = mv64x60_wdt_device_setup(np, id)))
|
|
||||||
printk(KERN_ERR "Failed to initialize MV64x60 "
|
|
||||||
"Watchdog %pOF: error %d.\n",
|
|
||||||
np, err);
|
|
||||||
of_node_put(np);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now add every node that is on the device bus */
|
|
||||||
for_each_compatible_node(np, NULL, "marvell,mv64360")
|
|
||||||
of_platform_bus_probe(np, of_mv64x60_devices, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
arch_initcall(mv64x60_device_setup);
|
|
||||||
|
|
||||||
static int __init mv64x60_add_mpsc_console(void)
|
|
||||||
{
|
|
||||||
struct device_node *np = NULL;
|
|
||||||
const char *prop;
|
|
||||||
|
|
||||||
prop = of_get_property(of_chosen, "linux,stdout-path", NULL);
|
|
||||||
if (prop == NULL)
|
|
||||||
goto not_mpsc;
|
|
||||||
|
|
||||||
np = of_find_node_by_path(prop);
|
|
||||||
if (!np)
|
|
||||||
goto not_mpsc;
|
|
||||||
|
|
||||||
if (!of_device_is_compatible(np, "marvell,mv64360-mpsc"))
|
|
||||||
goto not_mpsc;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "cell-index", NULL);
|
|
||||||
if (!prop)
|
|
||||||
goto not_mpsc;
|
|
||||||
|
|
||||||
add_preferred_console("ttyMM", *(int *)prop, NULL);
|
|
||||||
|
|
||||||
not_mpsc:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
console_initcall(mv64x60_add_mpsc_console);
|
|
|
@ -1,171 +0,0 @@
|
||||||
/*
|
|
||||||
* PCI bus setup for Marvell mv64360/mv64460 host bridges (Discovery)
|
|
||||||
*
|
|
||||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
|
||||||
*
|
|
||||||
* 2007 (c) MontaVista, Software, Inc. 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/stddef.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/stat.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
|
|
||||||
#include <asm/prom.h>
|
|
||||||
#include <asm/pci-bridge.h>
|
|
||||||
|
|
||||||
#define PCI_HEADER_TYPE_INVALID 0x7f /* Invalid PCI header type */
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSFS
|
|
||||||
/* 32-bit hex or dec stringified number + '\n' */
|
|
||||||
#define MV64X60_VAL_LEN_MAX 11
|
|
||||||
#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
|
|
||||||
|
|
||||||
static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj,
|
|
||||||
struct bin_attribute *attr, char *buf,
|
|
||||||
loff_t off, size_t count)
|
|
||||||
{
|
|
||||||
struct pci_dev *phb;
|
|
||||||
u32 v;
|
|
||||||
|
|
||||||
if (off > 0)
|
|
||||||
return 0;
|
|
||||||
if (count < MV64X60_VAL_LEN_MAX)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
|
||||||
if (!phb)
|
|
||||||
return -ENODEV;
|
|
||||||
pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
|
|
||||||
pci_dev_put(phb);
|
|
||||||
|
|
||||||
return sprintf(buf, "0x%08x\n", v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
|
|
||||||
struct bin_attribute *attr, char *buf,
|
|
||||||
loff_t off, size_t count)
|
|
||||||
{
|
|
||||||
struct pci_dev *phb;
|
|
||||||
u32 v;
|
|
||||||
|
|
||||||
if (off > 0)
|
|
||||||
return 0;
|
|
||||||
if (count <= 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (sscanf(buf, "%i", &v) != 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
|
||||||
if (!phb)
|
|
||||||
return -ENODEV;
|
|
||||||
pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
|
|
||||||
pci_dev_put(phb);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
|
|
||||||
.attr = {
|
|
||||||
.name = "hs_reg",
|
|
||||||
.mode = 0644,
|
|
||||||
},
|
|
||||||
.size = MV64X60_VAL_LEN_MAX,
|
|
||||||
.read = mv64x60_hs_reg_read,
|
|
||||||
.write = mv64x60_hs_reg_write,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init mv64x60_sysfs_init(void)
|
|
||||||
{
|
|
||||||
struct device_node *np;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
const unsigned int *prop;
|
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360");
|
|
||||||
if (!np)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
prop = of_get_property(np, "hs_reg_valid", NULL);
|
|
||||||
of_node_put(np);
|
|
||||||
|
|
||||||
pdev = platform_device_register_simple("marvell,mv64360", 0, NULL, 0);
|
|
||||||
if (IS_ERR(pdev))
|
|
||||||
return PTR_ERR(pdev);
|
|
||||||
|
|
||||||
return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
subsys_initcall(mv64x60_sysfs_init);
|
|
||||||
|
|
||||||
#endif /* CONFIG_SYSFS */
|
|
||||||
|
|
||||||
static void mv64x60_pci_fixup_early(struct pci_dev *dev)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Set the host bridge hdr_type to an invalid value so that
|
|
||||||
* pci_setup_device() will ignore the host bridge.
|
|
||||||
*/
|
|
||||||
dev->hdr_type = PCI_HEADER_TYPE_INVALID;
|
|
||||||
}
|
|
||||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360,
|
|
||||||
mv64x60_pci_fixup_early);
|
|
||||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460,
|
|
||||||
mv64x60_pci_fixup_early);
|
|
||||||
|
|
||||||
static int __init mv64x60_add_bridge(struct device_node *dev)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
struct pci_controller *hose;
|
|
||||||
struct resource rsrc;
|
|
||||||
const int *bus_range;
|
|
||||||
int primary;
|
|
||||||
|
|
||||||
memset(&rsrc, 0, sizeof(rsrc));
|
|
||||||
|
|
||||||
/* Fetch host bridge registers address */
|
|
||||||
if (of_address_to_resource(dev, 0, &rsrc)) {
|
|
||||||
printk(KERN_ERR "No PCI reg property in device tree\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get bus range if any */
|
|
||||||
bus_range = of_get_property(dev, "bus-range", &len);
|
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int))
|
|
||||||
printk(KERN_WARNING "Can't get bus-range for %pOF, assume"
|
|
||||||
" bus 0\n", dev);
|
|
||||||
|
|
||||||
hose = pcibios_alloc_controller(dev);
|
|
||||||
if (!hose)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
hose->first_busno = bus_range ? bus_range[0] : 0;
|
|
||||||
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
|
||||||
|
|
||||||
setup_indirect_pci(hose, rsrc.start, rsrc.start + 4, 0);
|
|
||||||
hose->self_busno = hose->first_busno;
|
|
||||||
|
|
||||||
printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
|
|
||||||
"Firmware bus number: %d->%d\n",
|
|
||||||
(unsigned long long)rsrc.start, hose->first_busno,
|
|
||||||
hose->last_busno);
|
|
||||||
|
|
||||||
/* Interpret the "ranges" property */
|
|
||||||
/* This also maps the I/O region and sets isa_io/mem_base */
|
|
||||||
primary = (hose->first_busno == 0);
|
|
||||||
pci_process_bridge_OF_ranges(hose, dev, primary);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init mv64x60_pci_init(void)
|
|
||||||
{
|
|
||||||
struct device_node *np;
|
|
||||||
|
|
||||||
for_each_compatible_node(np, "pci", "marvell,mv64360-pci")
|
|
||||||
mv64x60_add_bridge(np);
|
|
||||||
}
|
|
|
@ -1,297 +0,0 @@
|
||||||
/*
|
|
||||||
* Interrupt handling for Marvell mv64360/mv64460 host bridges (Discovery)
|
|
||||||
*
|
|
||||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
|
||||||
*
|
|
||||||
* 2007 (c) MontaVista, Software, Inc. 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/stddef.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/prom.h>
|
|
||||||
#include <asm/irq.h>
|
|
||||||
|
|
||||||
#include "mv64x60.h"
|
|
||||||
|
|
||||||
/* Interrupt Controller Interface Registers */
|
|
||||||
#define MV64X60_IC_MAIN_CAUSE_LO 0x0004
|
|
||||||
#define MV64X60_IC_MAIN_CAUSE_HI 0x000c
|
|
||||||
#define MV64X60_IC_CPU0_INTR_MASK_LO 0x0014
|
|
||||||
#define MV64X60_IC_CPU0_INTR_MASK_HI 0x001c
|
|
||||||
#define MV64X60_IC_CPU0_SELECT_CAUSE 0x0024
|
|
||||||
|
|
||||||
#define MV64X60_HIGH_GPP_GROUPS 0x0f000000
|
|
||||||
#define MV64X60_SELECT_CAUSE_HIGH 0x40000000
|
|
||||||
|
|
||||||
/* General Purpose Pins Controller Interface Registers */
|
|
||||||
#define MV64x60_GPP_INTR_CAUSE 0x0008
|
|
||||||
#define MV64x60_GPP_INTR_MASK 0x000c
|
|
||||||
|
|
||||||
#define MV64x60_LEVEL1_LOW 0
|
|
||||||
#define MV64x60_LEVEL1_HIGH 1
|
|
||||||
#define MV64x60_LEVEL1_GPP 2
|
|
||||||
|
|
||||||
#define MV64x60_LEVEL1_MASK 0x00000060
|
|
||||||
#define MV64x60_LEVEL1_OFFSET 5
|
|
||||||
|
|
||||||
#define MV64x60_LEVEL2_MASK 0x0000001f
|
|
||||||
|
|
||||||
#define MV64x60_NUM_IRQS 96
|
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(mv64x60_lock);
|
|
||||||
|
|
||||||
static void __iomem *mv64x60_irq_reg_base;
|
|
||||||
static void __iomem *mv64x60_gpp_reg_base;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interrupt Controller Handling
|
|
||||||
*
|
|
||||||
* The interrupt controller handles three groups of interrupts:
|
|
||||||
* main low: IRQ0-IRQ31
|
|
||||||
* main high: IRQ32-IRQ63
|
|
||||||
* gpp: IRQ64-IRQ95
|
|
||||||
*
|
|
||||||
* This code handles interrupts in two levels. Level 1 selects the
|
|
||||||
* interrupt group, and level 2 selects an IRQ within that group.
|
|
||||||
* Each group has its own irq_chip structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static u32 mv64x60_cached_low_mask;
|
|
||||||
static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
|
|
||||||
static u32 mv64x60_cached_gpp_mask;
|
|
||||||
|
|
||||||
static struct irq_domain *mv64x60_irq_host;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mv64x60_chip_low functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void mv64x60_mask_low(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_low_mask &= ~(1 << level2);
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
|
|
||||||
mv64x60_cached_low_mask);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mv64x60_unmask_low(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_low_mask |= 1 << level2;
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
|
|
||||||
mv64x60_cached_low_mask);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip mv64x60_chip_low = {
|
|
||||||
.name = "mv64x60_low",
|
|
||||||
.irq_mask = mv64x60_mask_low,
|
|
||||||
.irq_mask_ack = mv64x60_mask_low,
|
|
||||||
.irq_unmask = mv64x60_unmask_low,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mv64x60_chip_high functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void mv64x60_mask_high(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_high_mask &= ~(1 << level2);
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
|
|
||||||
mv64x60_cached_high_mask);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mv64x60_unmask_high(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_high_mask |= 1 << level2;
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
|
|
||||||
mv64x60_cached_high_mask);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip mv64x60_chip_high = {
|
|
||||||
.name = "mv64x60_high",
|
|
||||||
.irq_mask = mv64x60_mask_high,
|
|
||||||
.irq_mask_ack = mv64x60_mask_high,
|
|
||||||
.irq_unmask = mv64x60_unmask_high,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mv64x60_chip_gpp functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void mv64x60_mask_gpp(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_gpp_mask &= ~(1 << level2);
|
|
||||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
|
||||||
mv64x60_cached_gpp_mask);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mv64x60_mask_ack_gpp(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_gpp_mask &= ~(1 << level2);
|
|
||||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
|
||||||
mv64x60_cached_gpp_mask);
|
|
||||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE,
|
|
||||||
~(1 << level2));
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mv64x60_unmask_gpp(struct irq_data *d)
|
|
||||||
{
|
|
||||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
mv64x60_cached_gpp_mask |= 1 << level2;
|
|
||||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
|
||||||
mv64x60_cached_gpp_mask);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip mv64x60_chip_gpp = {
|
|
||||||
.name = "mv64x60_gpp",
|
|
||||||
.irq_mask = mv64x60_mask_gpp,
|
|
||||||
.irq_mask_ack = mv64x60_mask_ack_gpp,
|
|
||||||
.irq_unmask = mv64x60_unmask_gpp,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mv64x60_host_ops functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct irq_chip *mv64x60_chips[] = {
|
|
||||||
[MV64x60_LEVEL1_LOW] = &mv64x60_chip_low,
|
|
||||||
[MV64x60_LEVEL1_HIGH] = &mv64x60_chip_high,
|
|
||||||
[MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
|
|
||||||
irq_hw_number_t hwirq)
|
|
||||||
{
|
|
||||||
int level1;
|
|
||||||
|
|
||||||
irq_set_status_flags(virq, IRQ_LEVEL);
|
|
||||||
|
|
||||||
level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET;
|
|
||||||
BUG_ON(level1 > MV64x60_LEVEL1_GPP);
|
|
||||||
irq_set_chip_and_handler(virq, mv64x60_chips[level1],
|
|
||||||
handle_level_irq);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct irq_domain_ops mv64x60_host_ops = {
|
|
||||||
.map = mv64x60_host_map,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Global functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
void __init mv64x60_init_irq(void)
|
|
||||||
{
|
|
||||||
struct device_node *np;
|
|
||||||
phys_addr_t paddr;
|
|
||||||
unsigned int size;
|
|
||||||
const unsigned int *reg;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
|
|
||||||
reg = of_get_property(np, "reg", &size);
|
|
||||||
paddr = of_translate_address(np, reg);
|
|
||||||
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
|
|
||||||
of_node_put(np);
|
|
||||||
|
|
||||||
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-pic");
|
|
||||||
reg = of_get_property(np, "reg", &size);
|
|
||||||
paddr = of_translate_address(np, reg);
|
|
||||||
mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
|
|
||||||
|
|
||||||
mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
|
|
||||||
&mv64x60_host_ops, NULL);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
|
||||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
|
||||||
mv64x60_cached_gpp_mask);
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
|
|
||||||
mv64x60_cached_low_mask);
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
|
|
||||||
mv64x60_cached_high_mask);
|
|
||||||
|
|
||||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE, 0);
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_LO, 0);
|
|
||||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_HI, 0);
|
|
||||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int mv64x60_get_irq(void)
|
|
||||||
{
|
|
||||||
u32 cause;
|
|
||||||
int level1;
|
|
||||||
irq_hw_number_t hwirq;
|
|
||||||
int virq = 0;
|
|
||||||
|
|
||||||
cause = in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_SELECT_CAUSE);
|
|
||||||
if (cause & MV64X60_SELECT_CAUSE_HIGH) {
|
|
||||||
cause &= mv64x60_cached_high_mask;
|
|
||||||
level1 = MV64x60_LEVEL1_HIGH;
|
|
||||||
if (cause & MV64X60_HIGH_GPP_GROUPS) {
|
|
||||||
cause = in_le32(mv64x60_gpp_reg_base +
|
|
||||||
MV64x60_GPP_INTR_CAUSE);
|
|
||||||
cause &= mv64x60_cached_gpp_mask;
|
|
||||||
level1 = MV64x60_LEVEL1_GPP;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cause &= mv64x60_cached_low_mask;
|
|
||||||
level1 = MV64x60_LEVEL1_LOW;
|
|
||||||
}
|
|
||||||
if (cause) {
|
|
||||||
hwirq = (level1 << MV64x60_LEVEL1_OFFSET) | __ilog2(cause);
|
|
||||||
virq = irq_linear_revmap(mv64x60_irq_host, hwirq);
|
|
||||||
}
|
|
||||||
|
|
||||||
return virq;
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
* udbg serial input/output routines for the Marvell MV64x60 (Discovery).
|
|
||||||
*
|
|
||||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
|
||||||
*
|
|
||||||
* 2007 (c) MontaVista Software, Inc. 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 <asm/io.h>
|
|
||||||
#include <asm/prom.h>
|
|
||||||
#include <asm/udbg.h>
|
|
||||||
|
|
||||||
#include <sysdev/mv64x60.h>
|
|
||||||
|
|
||||||
#define MPSC_0_CR1_OFFSET 0x000c
|
|
||||||
|
|
||||||
#define MPSC_0_CR2_OFFSET 0x0010
|
|
||||||
#define MPSC_CHR_2_TCS (1 << 9)
|
|
||||||
|
|
||||||
#define MPSC_0_CHR_10_OFFSET 0x0030
|
|
||||||
|
|
||||||
#define MPSC_INTR_CAUSE_OFF_0 0x0004
|
|
||||||
#define MPSC_INTR_CAUSE_OFF_1 0x000c
|
|
||||||
#define MPSC_INTR_CAUSE_RCC (1<<6)
|
|
||||||
|
|
||||||
static void __iomem *mpsc_base;
|
|
||||||
static void __iomem *mpsc_intr_cause;
|
|
||||||
|
|
||||||
static void mv64x60_udbg_putc(char c)
|
|
||||||
{
|
|
||||||
if (c == '\n')
|
|
||||||
mv64x60_udbg_putc('\r');
|
|
||||||
|
|
||||||
while(in_le32(mpsc_base + MPSC_0_CR2_OFFSET) & MPSC_CHR_2_TCS)
|
|
||||||
;
|
|
||||||
out_le32(mpsc_base + MPSC_0_CR1_OFFSET, c);
|
|
||||||
out_le32(mpsc_base + MPSC_0_CR2_OFFSET, MPSC_CHR_2_TCS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mv64x60_udbg_testc(void)
|
|
||||||
{
|
|
||||||
return (in_le32(mpsc_intr_cause) & MPSC_INTR_CAUSE_RCC) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mv64x60_udbg_getc(void)
|
|
||||||
{
|
|
||||||
int cause = 0;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
while (!mv64x60_udbg_testc())
|
|
||||||
;
|
|
||||||
|
|
||||||
c = in_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2);
|
|
||||||
out_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2, c);
|
|
||||||
out_le32(mpsc_intr_cause, cause & ~MPSC_INTR_CAUSE_RCC);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mv64x60_udbg_getc_poll(void)
|
|
||||||
{
|
|
||||||
if (!mv64x60_udbg_testc())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return mv64x60_udbg_getc();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mv64x60_udbg_init(void)
|
|
||||||
{
|
|
||||||
struct device_node *np, *mpscintr, *stdout = NULL;
|
|
||||||
const char *path;
|
|
||||||
const phandle *ph;
|
|
||||||
struct resource r[2];
|
|
||||||
const int *block_index;
|
|
||||||
int intr_cause_offset;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
path = of_get_property(of_chosen, "linux,stdout-path", NULL);
|
|
||||||
if (!path)
|
|
||||||
return;
|
|
||||||
|
|
||||||
stdout = of_find_node_by_path(path);
|
|
||||||
if (!stdout)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for_each_compatible_node(np, NULL, "marvell,mv64360-mpsc") {
|
|
||||||
if (np == stdout)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
of_node_put(stdout);
|
|
||||||
if (!np)
|
|
||||||
return;
|
|
||||||
|
|
||||||
block_index = of_get_property(np, "cell-index", NULL);
|
|
||||||
if (!block_index)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
switch (*block_index) {
|
|
||||||
case 0:
|
|
||||||
intr_cause_offset = MPSC_INTR_CAUSE_OFF_0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
intr_cause_offset = MPSC_INTR_CAUSE_OFF_1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = of_address_to_resource(np, 0, &r[0]);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ph = of_get_property(np, "mpscintr", NULL);
|
|
||||||
mpscintr = of_find_node_by_phandle(*ph);
|
|
||||||
if (!mpscintr)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err = of_address_to_resource(mpscintr, 0, &r[1]);
|
|
||||||
of_node_put(mpscintr);
|
|
||||||
if (err)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
of_node_put(np);
|
|
||||||
|
|
||||||
mpsc_base = ioremap(r[0].start, resource_size(&r[0]));
|
|
||||||
if (!mpsc_base)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mpsc_intr_cause = ioremap(r[1].start, resource_size(&r[1]));
|
|
||||||
if (!mpsc_intr_cause) {
|
|
||||||
iounmap(mpsc_base);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mpsc_intr_cause += intr_cause_offset;
|
|
||||||
|
|
||||||
udbg_putc = mv64x60_udbg_putc;
|
|
||||||
udbg_getc = mv64x60_udbg_getc;
|
|
||||||
udbg_getc_poll = mv64x60_udbg_getc_poll;
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
of_node_put(np);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mv64x60_init_early(void)
|
|
||||||
{
|
|
||||||
mv64x60_udbg_init();
|
|
||||||
}
|
|
Loading…
Reference in a new issue