Commit 287dc4b7 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle:
 "More hardware support across the field including a bunch of device
  drivers.  The highlight however really are further steps towards
  device tree.

  This has been sitting in -next for ages.  All MIPS _defconfigs have
  been tested to boot or where I don't have hardware available, to at
  least build fine."

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (77 commits)
  MIPS: Loongson 1B: Add defconfig
  MIPS: Loongson 1B: Add board support
  MIPS: Netlogic: early console fix
  MIPS: Netlogic: Fix indentation of smpboot.S
  MIPS: Netlogic: remove cpu_has_dc_aliases define for XLP
  MIPS: Netlogic: Remove unused pcibios_fixups
  MIPS: Netlogic: Add XLP SoC devices in FDT
  MIPS: Netlogic: Add IRQ mappings for more devices
  MIPS: Netlogic: USB support for XLP
  MIPS: Netlogic: XLP PCIe controller support.
  MIPS: Netlogic: Platform changes for XLR/XLS I2C
  MIPS: Netlogic: Platform NAND/NOR flash support
  MIPS: Netlogic: Platform changes for XLS USB
  MIPS: Netlogic: Remove NETLOGIC_ prefix
  MIPS: Netlogic: SMP wakeup code update
  MIPS: Netlogic: Update comments in smpboot.S
  MIPS: BCM63XX: Add 96328avng reference board
  MIPS: Expose PCIe drivers for MIPS
  MIPS: BCM63XX: Add PCIe Support for BCM6328
  MIPS: BCM63XX: Move the PCI initialization into its own function
  ...
parents 720d8507 68d88485
* Compact Flash
The Cavium Compact Flash device is connected to the Octeon Boot Bus,
and is thus a child of the Boot Bus device. It can read and write
industry standard compact flash devices.
Properties:
- compatible: "cavium,ebt3000-compact-flash";
Compatibility with many Cavium evaluation boards.
- reg: The base address of the the CF chip select banks. Depending on
the device configuration, there may be one or two banks.
- cavium,bus-width: The width of the connection to the CF devices. Valid
values are 8 and 16.
- cavium,true-ide: Optional, if present the CF connection is in True IDE mode.
- cavium,dma-engine-handle: Optional, a phandle for the DMA Engine connected
to this device.
Example:
compact-flash@5,0 {
compatible = "cavium,ebt3000-compact-flash";
reg = <5 0 0x10000>, <6 0 0x10000>;
cavium,bus-width = <16>;
cavium,true-ide;
cavium,dma-engine-handle = <&dma0>;
};
* General Purpose Input Output (GPIO) bus.
Properties:
- compatible: "cavium,octeon-3860-gpio"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the GPIO unit's register bank.
- gpio-controller: This is a GPIO controller.
- #gpio-cells: Must be <2>. The first cell is the GPIO pin.
- interrupt-controller: The GPIO controller is also an interrupt
controller, many of its pins may be configured as an interrupt
source.
- #interrupt-cells: Must be <2>. The first cell is the GPIO pin
connected to the interrupt source. The second cell is the interrupt
triggering protocol and may have one of four values:
1 - edge triggered on the rising edge.
2 - edge triggered on the falling edge
4 - level triggered active high.
8 - level triggered active low.
- interrupts: Interrupt routing for each pin.
Example:
gpio-controller@1070000000800 {
#gpio-cells = <2>;
compatible = "cavium,octeon-3860-gpio";
reg = <0x10700 0x00000800 0x0 0x100>;
gpio-controller;
/* Interrupts are specified by two parts:
* 1) GPIO pin number (0..15)
* 2) Triggering (1 - edge rising
* 2 - edge falling
* 4 - level active high
* 8 - level active low)
*/
interrupt-controller;
#interrupt-cells = <2>;
/* The GPIO pin connect to 16 consecutive CUI bits */
interrupts = <0 16>, <0 17>, <0 18>, <0 19>,
<0 20>, <0 21>, <0 22>, <0 23>,
<0 24>, <0 25>, <0 26>, <0 27>,
<0 28>, <0 29>, <0 30>, <0 31>;
};
* Two Wire Serial Interface (TWSI) / I2C
- compatible: "cavium,octeon-3860-twsi"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the TWSI/I2C bus controller register bank.
- #address-cells: Must be <1>.
- #size-cells: Must be <0>. I2C addresses have no size component.
- interrupts: A single interrupt specifier.
- clock-frequency: The I2C bus clock rate in Hz.
Example:
twsi0: i2c@1180000001000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "cavium,octeon-3860-twsi";
reg = <0x11800 0x00001000 0x0 0x200>;
interrupts = <0 45>;
clock-frequency = <100000>;
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
};
tmp@4c {
compatible = "ti,tmp421";
reg = <0x4c>;
};
};
* Boot Bus
The Octeon Boot Bus is a configurable parallel bus with 8 chip
selects. Each chip select is independently configurable.
Properties:
- compatible: "cavium,octeon-3860-bootbus"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the Boot Bus' register bank.
- #address-cells: Must be <2>. The first cell is the chip select
within the bootbus. The second cell is the offset from the chip select.
- #size-cells: Must be <1>.
- ranges: There must be one one triplet of (child-bus-address,
parent-bus-address, length) for each active chip select. If the
length element for any triplet is zero, the chip select is disabled,
making it inactive.
The configuration parameters for each chip select are stored in child
nodes.
Configuration Properties:
- compatible: "cavium,octeon-3860-bootbus-config"
- cavium,cs-index: A single cell indicating the chip select that
corresponds to this configuration.
- cavium,t-adr: A cell specifying the ADR timing (in nS).
- cavium,t-ce: A cell specifying the CE timing (in nS).
- cavium,t-oe: A cell specifying the OE timing (in nS).
- cavium,t-we: A cell specifying the WE timing (in nS).
- cavium,t-rd-hld: A cell specifying the RD_HLD timing (in nS).
- cavium,t-wr-hld: A cell specifying the WR_HLD timing (in nS).
- cavium,t-pause: A cell specifying the PAUSE timing (in nS).
- cavium,t-wait: A cell specifying the WAIT timing (in nS).
- cavium,t-page: A cell specifying the PAGE timing (in nS).
- cavium,t-rd-dly: A cell specifying the RD_DLY timing (in nS).
- cavium,pages: A cell specifying the PAGES parameter (0 = 8 bytes, 1
= 2 bytes, 2 = 4 bytes, 3 = 8 bytes).
- cavium,wait-mode: Optional. If present, wait mode (WAITM) is selected.
- cavium,page-mode: Optional. If present, page mode (PAGEM) is selected.
- cavium,bus-width: A cell specifying the WIDTH parameter (in bits) of
the bus for this chip select.
- cavium,ale-mode: Optional. If present, ALE mode is selected.
- cavium,sam-mode: Optional. If present, SAM mode is selected.
- cavium,or-mode: Optional. If present, OR mode is selected.
Example:
bootbus: bootbus@1180000000000 {
compatible = "cavium,octeon-3860-bootbus";
reg = <0x11800 0x00000000 0x0 0x200>;
/* The chip select number and offset */
#address-cells = <2>;
/* The size of the chip select region */
#size-cells = <1>;
ranges = <0 0 0x0 0x1f400000 0xc00000>,
<1 0 0x10000 0x30000000 0>,
<2 0 0x10000 0x40000000 0>,
<3 0 0x10000 0x50000000 0>,
<4 0 0x0 0x1d020000 0x10000>,
<5 0 0x0 0x1d040000 0x10000>,
<6 0 0x0 0x1d050000 0x10000>,
<7 0 0x10000 0x90000000 0>;
cavium,cs-config@0 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <0>;
cavium,t-adr = <20>;
cavium,t-ce = <60>;
cavium,t-oe = <60>;
cavium,t-we = <45>;
cavium,t-rd-hld = <35>;
cavium,t-wr-hld = <45>;
cavium,t-pause = <0>;
cavium,t-wait = <0>;
cavium,t-page = <35>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,bus-width = <8>;
};
.
.
.
cavium,cs-config@6 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <6>;
cavium,t-adr = <5>;
cavium,t-ce = <300>;
cavium,t-oe = <270>;
cavium,t-we = <150>;
cavium,t-rd-hld = <100>;
cavium,t-wr-hld = <70>;
cavium,t-pause = <0>;
cavium,t-wait = <0>;
cavium,t-page = <320>;
cavium,t-rd-dly = <0>;
cavium,pages = <0>;
cavium,wait-mode;
cavium,bus-width = <16>;
};
.
.
.
};
* Central Interrupt Unit
Properties:
- compatible: "cavium,octeon-3860-ciu"
Compatibility with all cn3XXX, cn5XXX and cn63XX SOCs.
- interrupt-controller: This is an interrupt controller.
- reg: The base address of the CIU's register bank.
- #interrupt-cells: Must be <2>. The first cell is the bank within
the CIU and may have a value of 0 or 1. The second cell is the bit
within the bank and may have a value between 0 and 63.
Example:
interrupt-controller@1070000000000 {
compatible = "cavium,octeon-3860-ciu";
interrupt-controller;
/* Interrupts are specified by two parts:
* 1) Controller register (0 or 1)
* 2) Bit within the register (0..63)
*/
#interrupt-cells = <2>;
reg = <0x10700 0x00000000 0x0 0x7000>;
};
* Central Interrupt Unit
Properties:
- compatible: "cavium,octeon-6880-ciu2"
Compatibility with 68XX SOCs.
- interrupt-controller: This is an interrupt controller.
- reg: The base address of the CIU's register bank.
- #interrupt-cells: Must be <2>. The first cell is the bank within
the CIU and may have a value between 0 and 63. The second cell is
the bit within the bank and may also have a value between 0 and 63.
Example:
interrupt-controller@1070100000000 {
compatible = "cavium,octeon-6880-ciu2";
interrupt-controller;
/* Interrupts are specified by two parts:
* 1) Controller register (0..63)
* 2) Bit within the register (0..63)
*/
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <0x10701 0x00000000 0x0 0x4000000>;
};
* DMA Engine.
The Octeon DMA Engine transfers between the Boot Bus and main memory.
The DMA Engine will be refered to by phandle by any device that is
connected to it.
Properties:
- compatible: "cavium,octeon-5750-bootbus-dma"
Compatibility with all cn52XX, cn56XX and cn6XXX SOCs.
- reg: The base address of the DMA Engine's register bank.
- interrupts: A single interrupt specifier.
Example:
dma0: dma-engine@1180000000100 {
compatible = "cavium,octeon-5750-bootbus-dma";
reg = <0x11800 0x00000100 0x0 0x8>;
interrupts = <0 63>;
};
* UCTL USB controller glue
Properties:
- compatible: "cavium,octeon-6335-uctl"
Compatibility with all cn6XXX SOCs.
- reg: The base address of the UCTL register bank.
- #address-cells: Must be <2>.
- #size-cells: Must be <2>.
- ranges: Empty to signify direct mapping of the children.
- refclk-frequency: A single cell containing the reference clock
frequency in Hz.
- refclk-type: A string describing the reference clock connection
either "crystal" or "external".
Example:
uctl@118006f000000 {
compatible = "cavium,octeon-6335-uctl";
reg = <0x11800 0x6f000000 0x0 0x100>;
ranges; /* Direct mapping */
#address-cells = <2>;
#size-cells = <2>;
/* 12MHz, 24MHz and 48MHz allowed */
refclk-frequency = <24000000>;
/* Either "crystal" or "external" */
refclk-type = "crystal";
ehci@16f0000000000 {
compatible = "cavium,octeon-6335-ehci","usb-ehci";
reg = <0x16f00 0x00000000 0x0 0x100>;
interrupts = <0 56>;
big-endian-regs;
};
ohci@16f0000000400 {
compatible = "cavium,octeon-6335-ohci","usb-ohci";
reg = <0x16f00 0x00000400 0x0 0x100>;
interrupts = <0 56>;
big-endian-regs;
};
};
* System Management Interface (SMI) / MDIO
Properties:
- compatible: "cavium,octeon-3860-mdio"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the MDIO bus controller register bank.
- #address-cells: Must be <1>.
- #size-cells: Must be <0>. MDIO addresses have no size component.
Typically an MDIO bus might have several children.
Example:
mdio@1180000001800 {
compatible = "cavium,octeon-3860-mdio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x11800 0x00001800 0x0 0x40>;
ethernet-phy@0 {
...
reg = <0>;
};
};
* MIX Ethernet controller.
Properties:
- compatible: "cavium,octeon-5750-mix"
Compatibility with all cn5XXX and cn6XXX SOCs populated with MIX
devices.
- reg: The base addresses of four separate register banks. The first
bank contains the MIX registers. The second bank the corresponding
AGL registers. The third bank are the AGL registers shared by all
MIX devices present. The fourth bank is the AGL_PRT_CTL shared by
all MIX devices present.
- cell-index: A single cell specifying which portion of the shared
register banks corresponds to this MIX device.
- interrupts: Two interrupt specifiers. The first is the MIX
interrupt routing and the second the routing for the AGL interrupts.
- mac-address: Optional, the MAC address to assign to the device.
- local-mac-address: Optional, the MAC address to assign to the device
if mac-address is not specified.
- phy-handle: Optional, a phandle for the PHY device connected to this device.
Example:
ethernet@1070000100800 {
compatible = "cavium,octeon-5750-mix";
reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
<0x11800 0xE0000800 0x0 0x300>, /* AGL */
<0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
<0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
cell-index = <1>;
interrupts = <1 18>, < 1 46>;
local-mac-address = [ 00 0f b7 10 63 54 ];
phy-handle = <&phy1>;
};
* PIP Ethernet nexus.
The PIP Ethernet nexus can control several data packet input/output
devices. The devices have a two level grouping scheme. There may be
several interfaces, and each interface may have several ports. These
ports might be an individual Ethernet PHY.
Properties for the PIP nexus:
- compatible: "cavium,octeon-3860-pip"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the PIP's register bank.
- #address-cells: Must be <1>.
- #size-cells: Must be <0>.
Properties for PIP interfaces which is a child the PIP nexus:
- compatible: "cavium,octeon-3860-pip-interface"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The interface number.
- #address-cells: Must be <1>.
- #size-cells: Must be <0>.
Properties for PIP port which is a child the PIP interface:
- compatible: "cavium,octeon-3860-pip-port"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The port number within the interface group.
- mac-address: Optional, the MAC address to assign to the device.
- local-mac-address: Optional, the MAC address to assign to the device
if mac-address is not specified.
- phy-handle: Optional, a phandle for the PHY device connected to this device.
Example:
pip@11800a0000000 {
compatible = "cavium,octeon-3860-pip";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x11800 0xa0000000 0x0 0x2000>;
interface@0 {
compatible = "cavium,octeon-3860-pip-interface";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>; /* interface */
ethernet@0 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x0>; /* Port */
local-mac-address = [ 00 0f b7 10 63 60 ];
phy-handle = <&phy2>;
};
ethernet@1 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x1>; /* Port */
local-mac-address = [ 00 0f b7 10 63 61 ];
phy-handle = <&phy3>;
};
ethernet@2 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x2>; /* Port */
local-mac-address = [ 00 0f b7 10 63 62 ];
phy-handle = <&phy4>;
};
ethernet@3 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x3>; /* Port */
local-mac-address = [ 00 0f b7 10 63 63 ];
phy-handle = <&phy5>;
};
};
interface@1 {
compatible = "cavium,octeon-3860-pip-interface";
#address-cells = <1>;
#size-cells = <0>;
reg = <1>; /* interface */
ethernet@0 {
compatible = "cavium,octeon-3860-pip-port";
reg = <0x0>; /* Port */
local-mac-address = [ 00 0f b7 10 63 64 ];
phy-handle = <&phy6>;
};
};
};
* Universal Asynchronous Receiver/Transmitter (UART)
- compatible: "cavium,octeon-3860-uart"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the UART register bank.
- interrupts: A single interrupt specifier.
- current-speed: Optional, the current bit rate in bits per second.
Example:
uart1: serial@1180000000c00 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000c00 0x0 0x400>;
current-speed = <115200>;
interrupts = <0 35>;
};
......@@ -14,6 +14,7 @@ platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson
platforms += loongson1
platforms += mipssim
platforms += mti-malta
platforms += netlogic
......
......@@ -209,6 +209,7 @@ config MACH_JZ4740
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_ZBOOT_UART16550
select DMA_NONCOHERENT
select IRQ_CPU
select GENERIC_GPIO
......@@ -264,6 +265,16 @@ config MACH_LOONGSON
Chinese Academy of Sciences (CAS) in the People's Republic
of China. The chief architect is Professor Weiwu Hu.
config MACH_LOONGSON1
bool "Loongson 1 family of machines"
select SYS_SUPPORTS_ZBOOT
help
This enables support for the Loongson 1 based machines.
Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by
the ICT (Institute of Computing Technology) and the Chinese Academy
of Sciences.
config MIPS_MALTA
bool "MIPS Malta board"
select ARCH_MAY_HAVE_PC_FDC
......@@ -787,6 +798,8 @@ config NLM_XLR_BOARD
select ZONE_DMA if 64BIT
select SYNC_R4K
select SYS_HAS_EARLY_PRINTK
select USB_ARCH_HAS_OHCI if USB_SUPPORT
select USB_ARCH_HAS_EHCI if USB_SUPPORT
help
Support for systems based on Netlogic XLR and XLS processors.
Say Y here if you have a XLR or XLS based board.
......@@ -799,7 +812,6 @@ config NLM_XLP_BOARD
select SYS_HAS_CPU_XLP
select SYS_SUPPORTS_SMP
select HW_HAS_PCI
select SWAP_IO_SPACE
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select 64BIT_PHYS_ADDR
......@@ -836,6 +848,7 @@ source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson/Kconfig"
source "arch/mips/loongson1/Kconfig"
source "arch/mips/netlogic/Kconfig"
endmenu
......@@ -1217,6 +1230,14 @@ config CPU_LOONGSON2F
have a similar programming interface with FPGA northbridge used in
Loongson2E.
config CPU_LOONGSON1B
bool "Loongson 1B"
depends on SYS_HAS_CPU_LOONGSON1B
select CPU_LOONGSON1
help
The Loongson 1B is a 32-bit SoC, which implements the MIPS32
release 2 instruction set.
config CPU_MIPS32_R1
bool "MIPS32 Release 1"
depends on SYS_HAS_CPU_MIPS32_R1
......@@ -1432,6 +1453,8 @@ config CPU_CAVIUM_OCTEON
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select LIBFDT
select USE_OF
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
......@@ -1544,6 +1567,14 @@ config CPU_LOONGSON2
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
config CPU_LOONGSON1
bool
select CPU_MIPS32
select CPU_MIPSR2
select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
config CPU_BMIPS
bool
select CPU_MIPS32
......@@ -1562,6 +1593,9 @@ config SYS_HAS_CPU_LOONGSON2F
select CPU_SUPPORTS_ADDRWINCFG if 64BIT
select CPU_SUPPORTS_UNCACHED_ACCELERATED
config SYS_HAS_CPU_LOONGSON1B
bool
config SYS_HAS_CPU_MIPS32_R1
bool
......@@ -2366,6 +2400,8 @@ config PCI_DOMAINS
source "drivers/pci/Kconfig"
source "drivers/pci/pcie/Kconfig"
#
# ISA support is now enabled via select. Too many systems still have the one
# or other ISA chip on the board that users don't know about so don't expect
......
......@@ -81,10 +81,10 @@ static void mtx1_power_off(void)
void __init board_setup(void)
{
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
/* Enable USB power switch */
alchemy_gpio_direction_output(204, 0);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
/* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC);
......
......@@ -334,13 +334,12 @@ static void __init alchemy_setup_macs(int ctype)
if (alchemy_get_macs(ctype) < 1)
return;
macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
macres = kmemdup(au1xxx_eth0_resources[ctype],
sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
return;
}
memcpy(macres, au1xxx_eth0_resources[ctype],
sizeof(struct resource) * MAC_RES_COUNT);
au1xxx_eth0_device.resource = macres;
i = prom_get_ethernet_addr(ethaddr);
......@@ -356,13 +355,12 @@ static void __init alchemy_setup_macs(int ctype)
if (alchemy_get_macs(ctype) < 2)
return;
macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
macres = kmemdup(au1xxx_eth1_resources[ctype],
sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
return;
}
memcpy(macres, au1xxx_eth1_resources[ctype],
sizeof(struct resource) * MAC_RES_COUNT);
au1xxx_eth1_device.resource = macres;
ethaddr[5] += 1; /* next addr for 2nd MAC */
......
......@@ -2,7 +2,7 @@
# Alchemy Develboards
#
obj-y += prom.o bcsr.o platform.o
obj-y += bcsr.o platform.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_MIPS_PB1100) += pb1100.o
obj-$(CONFIG_MIPS_PB1500) += pb1500.o
......
......@@ -90,10 +90,7 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
disable_irq_nosync(irq);
for ( ; bisr; bisr &= bisr - 1)
generic_handle_irq(bcsr_csc_base + __ffs(bisr));
generic_handle_irq(bcsr_csc_base + __ffs(bisr));
enable_irq(irq);
}
......
......@@ -46,7 +46,7 @@ void __init board_setup(void)
alchemy_gpio1_input_enable();
udelay(100);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
{
u32 pin_func, sys_freqctrl, sys_clksrc;
......@@ -93,7 +93,7 @@ void __init board_setup(void)
pin_func |= SYS_PF_USB;
au_writel(pin_func, SYS_PINFUNC);
}
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
/* Enable sys bus clock divider when IDLE state or no bus activity. */
au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
......
......@@ -53,7 +53,7 @@ void __init board_setup(void)
alchemy_gpio_direction_input(201);
alchemy_gpio_direction_input(203);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
/* Zero and disable FREQ2 */
sys_freqctrl = au_readl(SYS_FREQCTRL0);
......@@ -87,7 +87,7 @@ void __init board_setup(void)
/* 2nd USB port is USB host */
pin_func |= SYS_PF_USB;
au_writel(pin_func, SYS_PINFUNC);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
#ifdef CONFIG_PCI
{
......
......@@ -10,9 +10,39 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = (int)fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
memsize = 64 << 20; /* all devboards have at least 64MB RAM */
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
#ifdef CONFIG_MIPS_DB1300
alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
#else
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
#endif
}
static struct platform_device db1x00_rtc_dev = {
.name = "rtc-au1xxx",
......
/*
* Common code used by all Alchemy develboards.
*
* Extracted from files which had this to say:
*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
#if defined(CONFIG_MIPS_DB1000) || \
defined(CONFIG_MIPS_PB1100) || \
defined(CONFIG_MIPS_PB1500)
#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
#else /* Au1550/Au1200-based develboards */
#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000
#endif
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = (int)fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
#ifdef CONFIG_MIPS_DB1300
alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
#else
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
#endif
}
menu "CPU support"
depends on BCM63XX
config BCM63XX_CPU_6328
bool "support 6328 CPU"
select HW_HAS_PCI
config BCM63XX_CPU_6338
bool "support 6338 CPU"
select HW_HAS_PCI
......
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \
dev-spi.o dev-uart.o dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
......@@ -11,9 +11,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/ssb/ssb.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
......@@ -24,7 +21,9 @@
#include <bcm63xx_dev_pci.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
......@@ -33,6 +32,48 @@ static struct bcm963xx_nvram nvram;
static unsigned int mac_addr_used;
static struct board_info board;
/*
* known 6328 boards
*/
#ifdef CONFIG_BCM63XX_CPU_6328
static struct board_info __initdata board_96328avng = {
.name = "96328avng",
.expected_cpu_id = 0x6328,
.has_uart0 = 1,
.has_pci = 1,
.leds = {
{
.name = "96328avng::ppp-fail",
.gpio = 2,
.active_low = 1,
},
{
.name = "96328avng::power",
.gpio = 4,
.active_low = 1,
.default_trigger = "default-on",
},
{
.name = "96328avng::power-fail",
.gpio = 8,
.active_low = 1,
},
{
.name = "96328avng::wps",
.gpio = 9,
.active_low = 1,
},
{
.name = "96328avng::ppp",
.gpio = 11,
.active_low = 1,
},
},
};
#endif
/*
* known 6338 boards
*/
......@@ -592,6 +633,9 @@ static struct board_info __initdata board_DWVS0 = {
* all boards
*/
static const struct board_info __initdata *bcm963xx_boards[] = {
#ifdef CONFIG_BCM63XX_CPU_6328
&board_96328avng,
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
&board_96338gw,
&board_96338w,
......@@ -709,9 +753,15 @@ void __init board_prom_init(void)
char cfe_version[32];
u32 val;
/* read base address of boot chip select (0) */
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;
/* read base address of boot chip select (0)
* 6328 does not have MPI but boots from a fixed address
*/
if (BCMCPU_IS_6328())
val = 0x18000000;
else {
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;
}
boot_addr = (u8 *)KSEG1ADDR(val);
/* dump cfe version */
......@@ -808,40 +858,6 @@ void __init board_setup(void)
panic("unexpected CPU for bcm963xx board");
}
static struct mtd_partition mtd_partitions[] = {
{
.name = "cfe",
.offset = 0x0,
.size = 0x40000,
}
};
static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
static struct physmap_flash_data flash_data = {
.width = 2,
.nr_parts = ARRAY_SIZE(mtd_partitions),
.parts = mtd_partitions,
.part_probe_types = bcm63xx_part_types,
};
static struct resource mtd_resources[] = {
{
.start = 0, /* filled at runtime */
.end = 0, /* filled at runtime */
.flags = IORESOURCE_MEM,
}
};
static struct platform_device mtd_dev = {
.name = "physmap-flash",
.resource = mtd_resources,
.num_resources = ARRAY_SIZE(mtd_resources),
.dev = {
.platform_data = &flash_data,
},
};
static struct gpio_led_platform_data bcm63xx_led_data;
static struct platform_device bcm63xx_gpio_leds = {
......@@ -855,8 +871,6 @@ static struct platform_device bcm63xx_gpio_leds = {
*/
int __init board_register_devices(void)
{
u32 val;
if (board.has_uart0)
bcm63xx_uart_register(0);
......@@ -890,14 +904,9 @@ int __init board_register_devices(void)
}
#endif
/* read base address of boot chip select (0) */
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;
mtd_resources[0].start = val;
mtd_resources[0].end = 0x1FFFFFFF;
bcm63xx_spi_register();
platform_device_register(&mtd_dev);
bcm63xx_flash_register();
bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
bcm63xx_led_data.leds = board.leds;
......
......@@ -120,7 +120,7 @@ static void enetsw_set(struct clk *clk, int enable)
{
if (!BCMCPU_IS_6368())
return;
bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN |
bcm_hwclock_set(CKCTL_6368_ROBOSW_EN |
CKCTL_6368_SWPKT_USB_EN |
CKCTL_6368_SWPKT_SAR_EN, enable);
if (enable) {
......@@ -163,7 +163,7 @@ static void usbh_set(struct clk *clk, int enable)
if (BCMCPU_IS_6348())
bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
else if (BCMCPU_IS_6368())
bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable);
bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
}
static struct clk clk_usbh = {
......@@ -181,9 +181,11 @@ static void spi_set(struct clk *clk, int enable)
mask = CKCTL_6338_SPI_EN;
else if (BCMCPU_IS_6348())
mask = CKCTL_6348_SPI_EN;
else
/* BCMCPU_IS_6358 */
else if (BCMCPU_IS_6358())
mask = CKCTL_6358_SPI_EN;
else
/* BCMCPU_IS_6368 */
mask = CKCTL_6368_SPI_EN;
bcm_hwclock_set(mask, enable);
}
......@@ -199,7 +201,7 @@ static void xtm_set(struct clk *clk, int enable)
if (!BCMCPU_IS_6368())
return;
bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN |
bcm_hwclock_set(CKCTL_6368_SAR_EN |
CKCTL_6368_SWPKT_SAR_EN, enable);
if (enable) {
......@@ -221,6 +223,18 @@ static struct clk clk_xtm = {
.set = xtm_set,
};
/*
* IPsec clock
*/
static void ipsec_set(struct clk *clk, int enable)
{
bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
}
static struct clk clk_ipsec = {
.set = ipsec_set,
};
/*
* Internal peripheral clock
*/
......@@ -278,6 +292,8 @@ struct clk *clk_get(struct device *dev, const char *id)
return &clk_periph;
if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
return &clk_pcm;
if (BCMCPU_IS_6368() && !strcmp(id, "ipsec"))
return &clk_ipsec;
return ERR_PTR(-ENOENT);
}
......
......@@ -29,6 +29,14 @@ static u16 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size;
static const unsigned long bcm6328_regs_base[] = {
__GEN_CPU_REGS_TABLE(6328)
};
static const int bcm6328_irqs[] = {
__GEN_CPU_IRQ_TABLE(6328)
};
static const unsigned long bcm6338_regs_base[] = {
__GEN_CPU_REGS_TABLE(6338)
};
......@@ -99,6 +107,33 @@ unsigned int bcm63xx_get_memory_size(void)
static unsigned int detect_cpu_clock(void)
{
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
{
unsigned int tmp, mips_pll_fcvo;
tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
>> STRAPBUS_6328_FCVO_SHIFT;
switch (mips_pll_fcvo) {
case 0x12:
case 0x14:
case 0x19:
return 160000000;
case 0x1c:
return 192000000;
case 0x13:
case 0x15:
return 200000000;
case 0x1a:
return 384000000;
case 0x16:
return 400000000;
default:
return 320000000;
}
}
case BCM6338_CPU_ID:
/* BCM6338 has a fixed 240 Mhz frequency */
return 240000000;
......@@ -170,6 +205,9 @@ static unsigned int detect_memory_size(void)
unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
u32 val;
if (BCMCPU_IS_6328())
return bcm_ddr_readl(DDR_CSEND_REG) << 24;
if (BCMCPU_IS_6345()) {
val = bcm_sdram_readl(SDRAM_MBASE_REG);
return (val * 8 * 1024 * 1024);
......@@ -228,17 +266,26 @@ void __init bcm63xx_cpu_init(void)
bcm63xx_irqs = bcm6345_irqs;
break;
case CPU_BMIPS4350:
switch (read_c0_prid() & 0xf0) {
case 0x10:
if ((read_c0_prid() & 0xf0) == 0x10) {
expected_cpu_id = BCM6358_CPU_ID;
bcm63xx_regs_base = bcm6358_regs_base;
bcm63xx_irqs = bcm6358_irqs;
break;
case 0x30:
expected_cpu_id = BCM6368_CPU_ID;
bcm63xx_regs_base = bcm6368_regs_base;
bcm63xx_irqs = bcm6368_irqs;
break;
} else {
/* all newer chips have the same chip id location */
u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);
switch (chip_id) {
case BCM6328_CPU_ID:
expected_cpu_id = BCM6328_CPU_ID;
bcm63xx_regs_base = bcm6328_regs_base;
bcm63xx_irqs = bcm6328_irqs;
break;
case BCM6368_CPU_ID:
expected_cpu_id = BCM6368_CPU_ID;
bcm63xx_regs_base = bcm6368_regs_base;
bcm63xx_irqs = bcm6368_irqs;
break;
}
}
break;
}
......
......@@ -31,7 +31,7 @@ static struct resource voip_dsp_resources[] = {
static struct platform_device bcm63xx_voip_dsp_device = {
.name = "bcm63xx-voip-dsp",
.id = 0,
.id = -1,
.num_resources = ARRAY_SIZE(voip_dsp_resources),
.resource = voip_dsp_resources,
};
......
/*
* Broadcom BCM63xx flash registration
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
* Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
* Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_dev_flash.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
static struct mtd_partition mtd_partitions[] = {
{
.name = "cfe",
.offset = 0x0,
.size = 0x40000,
}
};
static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
static struct physmap_flash_data flash_data = {
.width = 2,
.parts = mtd_partitions,
.part_probe_types = bcm63xx_part_types,
};
static struct resource mtd_resources[] = {
{
.start = 0, /* filled at runtime */
.end = 0, /* filled at runtime */
.flags = IORESOURCE_MEM,
}
};
static struct platform_device mtd_dev = {
.name = "physmap-flash",
.resource = mtd_resources,
.num_resources = ARRAY_SIZE(mtd_resources),
.dev = {
.platform_data = &flash_data,
},
};
static int __init bcm63xx_detect_flash_type(void)
{
u32 val;
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
val = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
return BCM63XX_FLASH_TYPE_SERIAL;
else
return BCM63XX_FLASH_TYPE_NAND;
case BCM6338_CPU_ID:
case BCM6345_CPU_ID:
case BCM6348_CPU_ID:
/* no way to auto detect so assume parallel */
return BCM63XX_FLASH_TYPE_PARALLEL;
case BCM6358_CPU_ID:
val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
return BCM63XX_FLASH_TYPE_PARALLEL;
else
return BCM63XX_FLASH_TYPE_SERIAL;
case BCM6368_CPU_ID:
val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
switch (val & STRAPBUS_6368_BOOT_SEL_MASK) {
case STRAPBUS_6368_BOOT_SEL_NAND:
return BCM63XX_FLASH_TYPE_NAND;
case STRAPBUS_6368_BOOT_SEL_SERIAL:
return BCM63XX_FLASH_TYPE_SERIAL;
case STRAPBUS_6368_BOOT_SEL_PARALLEL:
return BCM63XX_FLASH_TYPE_PARALLEL;
}
default:
return -EINVAL;
}
}
int __init bcm63xx_flash_register(void)
{
int flash_type;
u32 val;
flash_type = bcm63xx_detect_flash_type();
switch (flash_type) {
case BCM63XX_FLASH_TYPE_PARALLEL:
/* read base address of boot chip select (0) */
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;
mtd_resources[0].start = val;
mtd_resources[0].end = 0x1FFFFFFF;
return platform_device_register(&mtd_dev);
case BCM63XX_FLASH_TYPE_SERIAL:
pr_warn("unsupported serial flash detected\n");
return -ENODEV;
case BCM63XX_FLASH_TYPE_NAND:
pr_warn("unsupported NAND flash detected\n");
return -ENODEV;
default:
pr_err("flash detection failed for BCM%x: %d\n",
bcm63xx_get_cpu_id(), flash_type);
return -ENODEV;
}
}
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2011 Florian Fainelli <florian@openwrt.org>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <bcm63xx_cpu.h>
static struct resource rng_resources[] = {
{
.start = -1, /* filled at runtime */
.end = -1, /* filled at runtime */
.flags = IORESOURCE_MEM,
},
};
static struct platform_device bcm63xx_rng_device = {
.name = "bcm63xx-rng",
.id = -1,
.num_resources = ARRAY_SIZE(rng_resources),
.resource = rng_resources,
};
int __init bcm63xx_rng_register(void)
{
if (!BCMCPU_IS_6368())
return -ENODEV;
rng_resources[0].start = bcm63xx_regset_address(RSET_RNG);
rng_resources[0].end = rng_resources[0].start;
rng_resources[0].end += RSET_RNG_SIZE - 1;
return platform_device_register(&bcm63xx_rng_device);
}
arch_initcall(bcm63xx_rng_register);
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org>
* Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_dev_spi.h>
#include <bcm63xx_regs.h>
#ifdef BCMCPU_RUNTIME_DETECT
/*
* register offsets
*/
static const unsigned long bcm6338_regs_spi[] = {
__GEN_SPI_REGS_TABLE(6338)
};
static const unsigned long bcm6348_regs_spi[] = {
__GEN_SPI_REGS_TABLE(6348)
};
static const unsigned long bcm6358_regs_spi[] = {
__GEN_SPI_REGS_TABLE(6358)
};
static const unsigned long bcm6368_regs_spi[] = {
__GEN_SPI_REGS_TABLE(6368)
};
const unsigned long *bcm63xx_regs_spi;
EXPORT_SYMBOL(bcm63xx_regs_spi);
static __init void bcm63xx_spi_regs_init(void)
{
if (BCMCPU_IS_6338())
bcm63xx_regs_spi = bcm6338_regs_spi;
if (BCMCPU_IS_6348())
bcm63xx_regs_spi = bcm6348_regs_spi;
if (BCMCPU_IS_6358())
bcm63xx_regs_spi = bcm6358_regs_spi;
if (BCMCPU_IS_6368())
bcm63xx_regs_spi = bcm6368_regs_spi;
}
#else
static __init void bcm63xx_spi_regs_init(void) { }
#endif
static struct resource spi_resources[] = {
{
.start = -1, /* filled at runtime */
.end = -1, /* filled at runtime */
.flags = IORESOURCE_MEM,
},
{
.start = -1, /* filled at runtime */
.flags = IORESOURCE_IRQ,
},
};
static struct bcm63xx_spi_pdata spi_pdata = {
.bus_num = 0,
.num_chipselect = 8,
};
static struct platform_device bcm63xx_spi_device = {
.name = "bcm63xx-spi",
.id = -1,
.num_resources = ARRAY_SIZE(spi_resources),
.resource = spi_resources,
.dev = {
.platform_data = &spi_pdata,
},
};
int __init bcm63xx_spi_register(void)
{
struct clk *periph_clk;
if (BCMCPU_IS_6328() || BCMCPU_IS_6345())
return -ENODEV;
periph_clk = clk_get(NULL, "periph");
if (IS_ERR(periph_clk)) {
pr_err("unable to get periph clock\n");
return -ENODEV;
}
/* Set bus frequency */
spi_pdata.speed_hz = clk_get_rate(periph_clk);
spi_resources[0].start = bcm63xx_regset_address(RSET_SPI);
spi_resources[0].end = spi_resources[0].start;
spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
}
if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
}
bcm63xx_spi_regs_init();
return platform_device_register(&bcm63xx_spi_device);
}
......@@ -21,7 +21,7 @@ static struct resource wdt_resources[] = {
static struct platform_device bcm63xx_wdt_device = {
.name = "bcm63xx-wdt",
.id = 0,
.id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
......
......@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
#ifndef BCMCPU_RUNTIME_DETECT
#ifdef CONFIG_BCM63XX_CPU_6328
#define irq_stat_reg PERF_IRQSTAT_6328_REG
#define irq_mask_reg PERF_IRQMASK_6328_REG
#define irq_bits 64
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE)
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
#define irq_stat_reg PERF_IRQSTAT_6338_REG
#define irq_mask_reg PERF_IRQMASK_6338_REG
......@@ -118,6 +129,16 @@ static void bcm63xx_init_irq(void)
irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6328_REG;
irq_mask_addr += PERF_IRQMASK_6328_REG;
irq_bits = 64;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
break;
case BCM6338_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
......
......@@ -26,7 +26,9 @@ void __init prom_init(void)
bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
/* disable all hardware blocks clock for now */
if (BCMCPU_IS_6338())
if (BCMCPU_IS_6328())
mask = CKCTL_6328_ALL_SAFE_EN;
else if (BCMCPU_IS_6338())
mask = CKCTL_6338_ALL_SAFE_EN;
else if (BCMCPU_IS_6345())
mask = CKCTL_6345_ALL_SAFE_EN;
......
......@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void)
/* mask and clear all external irq */
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
break;
case BCM6338_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
break;
......@@ -95,9 +98,13 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot();
printk(KERN_INFO "triggering watchdog soft-reset...\n");
reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
reg |= SYS_PLL_SOFT_RESET;
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
if (BCMCPU_IS_6328()) {
bcm_wdt_writel(1, WDT_SOFTRESET_REG);
} else {
reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
reg |= SYS_PLL_SOFT_RESET;
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
}
while (1)
;
}
......
......@@ -58,8 +58,12 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
# Calculate the load address of the compressed kernel image
hostprogs-y := calc_vmlinuz_load_addr
ifeq ($(CONFIG_MACH_JZ4740),y)
VMLINUZ_LOAD_ADDRESS := 0x80600000
else
VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
$(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
endif
vmlinuzobjs-y += $(obj)/piggy.o
......
......@@ -18,6 +18,11 @@
#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
#endif
#ifdef CONFIG_MACH_JZ4740
#define UART0_BASE 0xB0030000
#define PORT(offset) (UART0_BASE + (4 * offset))
#endif
#ifndef PORT
#error please define the serial port address for your own machine
#endif
......
......@@ -9,9 +9,25 @@
# Copyright (C) 2005-2009 Cavium Networks
#
CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
obj-y += executive/
obj-$(CONFIG_SMP) += smp.o
DTS_FILES = octeon_3xxx.dts octeon_68xx.dts
DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES))
obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES))
$(obj)/%.dtb: $(src)/%.dts FORCE
$(call if_changed_dep,dtc)
# Let's keep the .dtb files around in case we want to look at them.
.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES))
clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES))
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file 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 file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/**
* @file
*
* Support library for the hardware Free Pool Allocator.
*
*
*/
#include "cvmx-config.h"
#include "cvmx.h"
#include "cvmx-fpa.h"
#include "cvmx-ipd.h"
/**
* Current state of all the pools. Use access functions
* instead of using it directly.
*/
CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
/**
* Setup a FPA pool to control a new block of memory. The
* buffer pointer must be a physical address.
*
* @pool: Pool to initialize
* 0 <= pool < 8
* @name: Constant character string to name this pool.
* String is not copied.
* @buffer: Pointer to the block of memory to use. This must be
* accessible by all processors and external hardware.
* @block_size: Size for each block controlled by the FPA
* @num_blocks: Number of blocks
*
* Returns 0 on Success,
* -1 on failure
*/
int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
uint64_t block_size, uint64_t num_blocks)
{
char *ptr;
if (!buffer) {
cvmx_dprintf
("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
return -1;
}
if (pool >= CVMX_FPA_NUM_POOLS) {
cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
return -1;
}
if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
cvmx_dprintf
("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
return -1;
}
if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
cvmx_dprintf
("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
return -1;
}
cvmx_fpa_pool_info[pool].name = name;
cvmx_fpa_pool_info[pool].size = block_size;
cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
cvmx_fpa_pool_info[pool].base = buffer;
ptr = (char *)buffer;
while (num_blocks--) {
cvmx_fpa_free(ptr, pool, 0);
ptr += block_size;
}
return 0;
}
/**
* Shutdown a Memory pool and validate that it had all of
* the buffers originally placed in it.
*
* @pool: Pool to shutdown
* Returns Zero on success
* - Positive is count of missing buffers
* - Negative is too many buffers or corrupted pointers
*/
uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
{
uint64_t errors = 0;
uint64_t count = 0;
uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
uint64_t finish =
base +
cvmx_fpa_pool_info[pool].size *
cvmx_fpa_pool_info[pool].starting_element_count;
void *ptr;
uint64_t address;
count = 0;
do {
ptr = cvmx_fpa_alloc(pool);
if (ptr)
address = cvmx_ptr_to_phys(ptr);
else
address = 0;
if (address) {
if ((address >= base) && (address < finish) &&
(((address -
base) % cvmx_fpa_pool_info[pool].size) == 0)) {
count++;
} else {
cvmx_dprintf
("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
(unsigned long long)address,
cvmx_fpa_pool_info[pool].name, (int)pool);
errors++;
}
}
} while (address);
#ifdef CVMX_ENABLE_PKO_FUNCTIONS
if (pool == 0)
cvmx_ipd_free_ptr();
#endif
if (errors) {
cvmx_dprintf
("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
cvmx_fpa_pool_info[pool].name, (int)pool,
(unsigned long long)base, (unsigned long long)finish,
(unsigned long long)cvmx_fpa_pool_info[pool].size);
return -errors;
} else
return 0;
}
uint64_t cvmx_fpa_get_block_size(uint64_t pool)
{
switch (pool) {
case 0:
return CVMX_FPA_POOL_0_SIZE;
case 1:
return CVMX_FPA_POOL_1_SIZE;
case 2:
return CVMX_FPA_POOL_2_SIZE;
case 3:
return CVMX_FPA_POOL_3_SIZE;
case 4:
return CVMX_FPA_POOL_4_SIZE;
case 5:
return CVMX_FPA_POOL_5_SIZE;
case 6:
return CVMX_FPA_POOL_6_SIZE;
case 7:
return CVMX_FPA_POOL_7_SIZE;
default:
return 0;
}
}
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file 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 file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/**
* @file
*
* Helper functions for FPA setup.
*
*/
#include "executive-config.h"
#include "cvmx-config.h"
#include "cvmx.h"
#include "cvmx-bootmem.h"
#include "cvmx-fpa.h"
#include "cvmx-helper-fpa.h"
/**
* Allocate memory for and initialize a single FPA pool.
*
* @pool: Pool to initialize
* @buffer_size: Size of buffers to allocate in bytes
* @buffers: Number of buffers to put in the pool. Zero is allowed
* @name: String name of the pool for debugging purposes
* Returns Zero on success, non-zero on failure
*/
static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
uint64_t buffers, const char *name)
{
uint64_t current_num;
void *memory;
uint64_t align = CVMX_CACHE_LINE_SIZE;
/*
* Align the allocation so that power of 2 size buffers are
* naturally aligned.
*/
while (align < buffer_size)
align = align << 1;
if (buffers == 0)
return 0;
current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool));
if (current_num) {
cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. "
"Skipping setup.\n",
pool, name, (unsigned long long)current_num);
return 0;
}
memory = cvmx_bootmem_alloc(buffer_size * buffers, align);
if (memory == NULL) {
cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n",
pool, name);
return -1;
}
cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
return 0;
}
/**
* Allocate memory and initialize the FPA pools using memory
* from cvmx-bootmem. Specifying zero for the number of
* buffers will cause that FPA pool to not be setup. This is
* useful if you aren't using some of the hardware and want
* to save memory. Use cvmx_helper_initialize_fpa instead of
* this function directly.
*
* @pip_pool: Should always be CVMX_FPA_PACKET_POOL
* @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
* @pip_buffers:
* Number of packet buffers.
* @wqe_pool: Should always be CVMX_FPA_WQE_POOL
* @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE
* @wqe_entries:
* Number of work queue entries
* @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
* @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
* @pko_buffers:
* PKO Command buffers. You should at minimum have two per
* each PKO queue.
* @tim_pool: Should always be CVMX_FPA_TIMER_POOL
* @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
* @tim_buffers:
* TIM ring buffer command queues. At least two per timer bucket
* is recommened.
* @dfa_pool: Should always be CVMX_FPA_DFA_POOL
* @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
* @dfa_buffers:
* DFA command buffer. A relatively small (32 for example)
* number should work.
* Returns Zero on success, non-zero if out of memory
*/
static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size,
int pip_buffers, int wqe_pool,
int wqe_size, int wqe_entries,
int pko_pool, int pko_size,
int pko_buffers, int tim_pool,
int tim_size, int tim_buffers,
int dfa_pool, int dfa_size,
int dfa_buffers)
{
int status;
cvmx_fpa_enable();
if ((pip_buffers > 0) && (pip_buffers <= 64))
cvmx_dprintf
("Warning: %d packet buffers may not be enough for hardware"
" prefetch. 65 or more is recommended.\n", pip_buffers);
if (pip_pool >= 0) {
status =
__cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
pip_buffers,
"Packet Buffers");
if (status)
return status;
}
if (wqe_pool >= 0) {
status =
__cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
wqe_entries,
"Work Queue Entries");
if (status)
return status;
}
if (pko_pool >= 0) {
status =
__cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
pko_buffers,
"PKO Command Buffers");
if (status)
return status;
}
if (tim_pool >= 0) {
status =
__cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
tim_buffers,
"TIM Command Buffers");
if (status)
return status;
}
if (dfa_pool >= 0) {
status =
__cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
dfa_buffers,
"DFA Command Buffers");
if (status)
return status;
}
return 0;
}
/**
* Allocate memory and initialize the FPA pools using memory
* from cvmx-bootmem. Sizes of each element in the pools is
* controlled by the cvmx-config.h header file. Specifying
* zero for any parameter will cause that FPA pool to not be
* setup. This is useful if you aren't using some of the
* hardware and want to save memory.
*
* @packet_buffers:
* Number of packet buffers to allocate
* @work_queue_entries:
* Number of work queue entries
* @pko_buffers:
* PKO Command buffers. You should at minimum have two per
* each PKO queue.
* @tim_buffers:
* TIM ring buffer command queues. At least two per timer bucket
* is recommened.
* @dfa_buffers:
* DFA command buffer. A relatively small (32 for example)
* number should work.
* Returns Zero on success, non-zero if out of memory
*/
int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
int pko_buffers, int tim_buffers,
int dfa_buffers)
{
#ifndef CVMX_FPA_PACKET_POOL
#define CVMX_FPA_PACKET_POOL -1
#define CVMX_FPA_PACKET_POOL_SIZE 0
#endif
#ifndef CVMX_FPA_WQE_POOL
#define CVMX_FPA_WQE_POOL -1
#define CVMX_FPA_WQE_POOL_SIZE 0
#endif
#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
#endif
#ifndef CVMX_FPA_TIMER_POOL
#define CVMX_FPA_TIMER_POOL -1
#define CVMX_FPA_TIMER_POOL_SIZE 0
#endif
#ifndef CVMX_FPA_DFA_POOL
#define CVMX_FPA_DFA_POOL -1
#define CVMX_FPA_DFA_POOL_SIZE 0
#endif
return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL,
CVMX_FPA_PACKET_POOL_SIZE,
packet_buffers, CVMX_FPA_WQE_POOL,
CVMX_FPA_WQE_POOL_SIZE,
work_queue_entries,
CVMX_FPA_OUTPUT_BUFFER_POOL,
CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
pko_buffers, CVMX_FPA_TIMER_POOL,
CVMX_FPA_TIMER_POOL_SIZE,
tim_buffers, CVMX_FPA_DFA_POOL,
CVMX_FPA_DFA_POOL_SIZE,
dfa_buffers);
}
This diff is collapsed.
......@@ -163,6 +163,14 @@
.set noreorder
.set noat
/*
* t7 is used as a flag to note inatomic mode.
*/
LEAF(__copy_user_inatomic)
b __copy_user_common
li t7, 1
END(__copy_user_inatomic)
/*
* A combined memcpy/__copy_user
* __copy_user sets len to 0 for success; else to an upper bound of
......@@ -174,6 +182,8 @@ LEAF(memcpy) /* a0=dst a1=src a2=len */
move v0, dst /* return value */
__memcpy:
FEXPORT(__copy_user)
li t7, 0 /* not inatomic */
__copy_user_common:
/*
* Note: dst & src may be unaligned, len may be 0
* Temps
......@@ -412,7 +422,6 @@ l_exc_copy:
* Assumes src < THREAD_BUADDR($28)
*/
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0)
1:
EXC( lb t1, 0(src), l_exc)
......@@ -422,10 +431,9 @@ EXC( lb t1, 0(src), l_exc)
ADD dst, dst, 1
l_exc:
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
nop
SUB len, AT, t0 # len number of uncopied bytes
bnez t7, 2f /* Skip the zeroing out part if inatomic */
/*
* Here's where we rely on src and dst being incremented in tandem,
* See (3) above.
......@@ -443,7 +451,7 @@ l_exc:
ADD dst, dst, 1
bnez src, 1b
SUB src, src, 1
jr ra
2: jr ra
nop
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -43,95 +43,67 @@ void octeon_serial_out(struct uart_port *up, int offset, int value)
cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
}
/*
* Allocated in .bss, so it is all zeroed.
*/
#define OCTEON_MAX_UARTS 3
static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1];
static struct platform_device octeon_uart8250_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = octeon_uart8250_data,
},
};
static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
static int __devinit octeon_serial_probe(struct platform_device *pdev)
{
p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
p->type = PORT_OCTEON;
p->iotype = UPIO_MEM;
p->regshift = 3; /* I/O addresses are every 8 bytes */
int irq, res;
struct resource *res_mem;
struct uart_port port;
/* All adaptors have an irq. */
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
memset(&port, 0, sizeof(port));
port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
port.type = PORT_OCTEON;
port.iotype = UPIO_MEM;
port.regshift = 3;
port.dev = &pdev->dev;
if (octeon_is_simulation())
/* Make simulator output fast*/
p->uartclk = 115200 * 16;
port.uartclk = 115200 * 16;
else
p->uartclk = octeon_get_io_clock_rate();
p->serial_in = octeon_serial_in;
p->serial_out = octeon_serial_out;
}
port.uartclk = octeon_get_io_clock_rate();
static int __init octeon_serial_init(void)
{
int enable_uart0;
int enable_uart1;
int enable_uart2;
struct plat_serial8250_port *p;
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
/*
* If we are configured to run as the second of two kernels,
* disable uart0 and enable uart1. Uart0 is owned by the first
* kernel
*/
enable_uart0 = 0;
enable_uart1 = 1;
#else
/*
* We are configured for the first kernel. We'll enable uart0
* if the bootloader told us to use 0, otherwise will enable
* uart 1.
*/
enable_uart0 = (octeon_get_boot_uart() == 0);
enable_uart1 = (octeon_get_boot_uart() == 1);
#ifdef CONFIG_KGDB
enable_uart1 = 1;
#endif
#endif
/* Right now CN52XX is the only chip with a third uart */
enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX);
p = octeon_uart8250_data;
if (enable_uart0) {
/* Add a ttyS device for hardware uart 0 */
octeon_uart_set_common(p);
p->membase = (void *) CVMX_MIO_UARTX_RBR(0);
p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1);
p->irq = OCTEON_IRQ_UART0;
p++;
}
port.serial_in = octeon_serial_in;
port.serial_out = octeon_serial_out;
port.irq = irq;
if (enable_uart1) {
/* Add a ttyS device for hardware uart 1 */
octeon_uart_set_common(p);
p->membase = (void *) CVMX_MIO_UARTX_RBR(1);
p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1);
p->irq = OCTEON_IRQ_UART1;
p++;
}
if (enable_uart2) {
/* Add a ttyS device for hardware uart 2 */
octeon_uart_set_common(p);
p->membase = (void *) CVMX_MIO_UART2_RBR;
p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1);
p->irq = OCTEON_IRQ_UART2;
p++;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res_mem == NULL) {
dev_err(&pdev->dev, "found no memory resource\n");
return -ENXIO;
}
port.mapbase = res_mem->start;
port.membase = ioremap(res_mem->start, resource_size(res_mem));
BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);
res = serial8250_register_port(&port);
return platform_device_register(&octeon_uart8250_device);
return res >= 0 ? 0 : res;
}
device_initcall(octeon_serial_init);
static struct of_device_id octeon_serial_match[] = {
{
.compatible = "cavium,octeon-3860-uart",
},
{},
};
MODULE_DEVICE_TABLE(of, octeon_serial_match);
static struct platform_driver octeon_serial_driver = {
.probe = octeon_serial_probe,
.driver = {
.owner = THIS_MODULE,
.name = "octeon_serial",
.of_match_table = octeon_serial_match,
},
};
static int __init octeon_serial_init(void)
{
return platform_driver_register(&octeon_serial_driver);
}
late_initcall(octeon_serial_init);
......@@ -21,6 +21,8 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/of_fdt.h>
#include <linux/libfdt.h>
#include <asm/processor.h>
#include <asm/reboot.h>
......@@ -775,3 +777,46 @@ void prom_free_prom_memory(void)
}
#endif
}
int octeon_prune_device_tree(void);
extern const char __dtb_octeon_3xxx_begin;
extern const char __dtb_octeon_3xxx_end;
extern const char __dtb_octeon_68xx_begin;
extern const char __dtb_octeon_68xx_end;
void __init device_tree_init(void)
{
int dt_size;
struct boot_param_header *fdt;
bool do_prune;
if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
if (fdt_check_header(fdt))
panic("Corrupt Device Tree passed to kernel.");
dt_size = be32_to_cpu(fdt->totalsize);
do_prune = false;
} else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin;
dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin;
do_prune = true;
} else {
fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin;
dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
do_prune = true;
}
/* Copy the default tree from init memory. */
initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
if (initial_boot_params == NULL)
panic("Could not allocate initial_boot_params\n");
memcpy(initial_boot_params, fdt, dt_size);
if (do_prune) {
octeon_prune_device_tree();
pr_info("Using internal Device Tree.\n");
} else {
pr_info("Using passed Device Tree.\n");
}
unflatten_device_tree();
}
CONFIG_MACH_LOONGSON1=y
CONFIG_PREEMPT=y
# CONFIG_SECCOMP is not set
CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_EXPERT=y
CONFIG_PERF_EVENTS=y
# CONFIG_COMPAT_BRK is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_SUSPEND is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_SYN_COOKIES=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_SCSI=m
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=m
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CHELSIO is not set
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_DA=y
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_LEGACY_PTY_COUNT=8
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
# CONFIG_VGA_CONSOLE is not set
CONFIG_USB_HID=m
CONFIG_HID_GENERIC=m
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_STORAGE=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_LOONGSON1=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
# CONFIG_DNOTIFY is not set
CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_FTRACE is not set
# CONFIG_EARLY_PRINTK is not set
......@@ -367,6 +367,10 @@ CONFIG_SERIAL_8250_RSA=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_RAW_DRIVER=m
CONFIG_I2C=y
CONFIG_I2C_XLR=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1374=y
# CONFIG_HWMON is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID_SUPPORT is not set
......
......@@ -101,7 +101,7 @@ void __init prom_free_prom_memory(void)
* the first page reserved for the exception handlers.
*/
#if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE)
#if IS_ENABLED(CONFIG_DECLANCE)
/*
* Leave 128 KB reserved for Lance memory for
* IOASIC DECstations.
......
......@@ -197,6 +197,7 @@
#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */
#define PRID_REV_VR4130 0x0080
#define PRID_REV_34K_V1_0_2 0x0022
#define PRID_REV_LOONGSON1B 0x0020
#define PRID_REV_LOONGSON2E 0x0002
#define PRID_REV_LOONGSON2F 0x0003
......@@ -261,7 +262,7 @@ enum cpu_type_enum {
*/
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC,
CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
/*
* MIPS64 class processors
......
#ifndef __BCM63XX_FLASH_H
#define __BCM63XX_FLASH_H
enum {
BCM63XX_FLASH_TYPE_PARALLEL,
BCM63XX_FLASH_TYPE_SERIAL,
BCM63XX_FLASH_TYPE_NAND,
};
int __init bcm63xx_flash_register(void);
#endif /* __BCM63XX_FLASH_H */
#ifndef BCM63XX_DEV_SPI_H
#define BCM63XX_DEV_SPI_H
#include <linux/types.h>
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
int __init bcm63xx_spi_register(void);
struct bcm63xx_spi_pdata {
unsigned int fifo_size;
int bus_num;
int num_chipselect;
u32 speed_hz;
};
enum bcm63xx_regs_spi {
SPI_CMD,
SPI_INT_STATUS,
SPI_INT_MASK_ST,
SPI_INT_MASK,
SPI_ST,
SPI_CLK_CFG,
SPI_FILL_BYTE,
SPI_MSG_TAIL,
SPI_RX_TAIL,
SPI_MSG_CTL,
SPI_MSG_DATA,
SPI_RX_DATA,
};
#define __GEN_SPI_RSET_BASE(__cpu, __rset) \
case SPI_## __rset: \
return SPI_## __cpu ##_## __rset;
#define __GEN_SPI_RSET(__cpu) \
switch (reg) { \
__GEN_SPI_RSET_BASE(__cpu, CMD) \
__GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \
__GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \
__GEN_SPI_RSET_BASE(__cpu, INT_MASK) \
__GEN_SPI_RSET_BASE(__cpu, ST) \
__GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \
__GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \
__GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \
__GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \
__GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \
__GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \
__GEN_SPI_RSET_BASE(__cpu, RX_DATA) \
}
#define __GEN_SPI_REGS_TABLE(__cpu) \
[SPI_CMD] = SPI_## __cpu ##_CMD, \
[SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \
[SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \
[SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \
[SPI_ST] = SPI_## __cpu ##_ST, \
[SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \
[SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \
[SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \
[SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \
[SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \
[SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \
[SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA,
static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg)
{
#ifdef BCMCPU_RUNTIME_DETECT
extern const unsigned long *bcm63xx_regs_spi;
return bcm63xx_regs_spi[reg];
#else
#ifdef CONFIG_BCM63XX_CPU_6338
__GEN_SPI_RSET(6338)
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
__GEN_SPI_RSET(6348)
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
__GEN_SPI_RSET(6358)
#endif
#ifdef CONFIG_BCM63XX_CPU_6368
__GEN_SPI_RSET(6368)
#endif
#endif
return 0;
}
#endif /* BCM63XX_DEV_SPI_H */
......@@ -9,6 +9,8 @@ int __init bcm63xx_gpio_init(void);
static inline unsigned long bcm63xx_gpio_count(void)
{
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
return 32;
case BCM6358_CPU_ID:
return 40;
case BCM6338_CPU_ID:
......
......@@ -40,6 +40,10 @@
#define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \
BCM_CB_MEM_SIZE - 1)
#define BCM_PCIE_MEM_BASE_PA 0x10f00000
#define BCM_PCIE_MEM_SIZE (16 * 1024 * 1024)
#define BCM_PCIE_MEM_END_PA (BCM_PCIE_MEM_BASE_PA + \
BCM_PCIE_MEM_SIZE - 1)
/*
* Internal registers are accessed through KSEG3
......@@ -85,11 +89,15 @@
#define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o))
#define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o))
#define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o))
#define bcm_pcie_readl(o) bcm_rset_readl(RSET_PCIE, (o))
#define bcm_pcie_writel(v, o) bcm_rset_writel(RSET_PCIE, (v), (o))
#define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o))
#define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o))
#define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o))
#define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o))
#define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o))
#define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o))
#define bcm_misc_readl(o) bcm_rset_readl(RSET_MISC, (o))
#define bcm_misc_writel(v, o) bcm_rset_writel(RSET_MISC, (v), (o))
#endif /* ! BCM63XX_IO_H_ */
......@@ -18,6 +18,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset)
if (offset >= 0xfff00000)
return 1;
break;
case BCM6328_CPU_ID:
case BCM6368_CPU_ID:
if (offset >= 0xb0000000 && offset < 0xb1000000)
return 1;
......
......@@ -19,6 +19,8 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#define JZ_NAND_NUM_BANKS 4
struct jz_nand_platform_data {
int num_partitions;
struct mtd_partition *partitions;
......@@ -27,6 +29,8 @@ struct jz_nand_platform_data {
unsigned int busy_gpio;
unsigned char banks[JZ_NAND_NUM_BANKS];
void (*ident_callback)(struct platform_device *, struct nand_chip *,
struct mtd_partition **, int *num_partitions);
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -48,7 +48,6 @@
#define cpu_has_userlocal 1
#define cpu_has_mips32r2 1
#define cpu_has_mips64r2 1
#define cpu_has_dc_aliases 1
#else
#error "Unknown Netlogic CPU"
#endif
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment