Commit 13bbd8d9 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (25 commits)
  [POWERPC] Add support for the mpc832x mds board
  [POWERPC] Add initial support for the e300c2 core
  [POWERPC] Add MPC8360EMDS default dts file
  [POWERPC] Add MPC8360EMDS board support
  [POWERPC] Add QUICC Engine (QE) infrastructure
  [POWERPC] Add QE device tree node definition
  [POWERPC] Don't try to just continue if xmon has no input device
  [POWERPC] Fix a printk in pseries_mpic_init_IRQ
  [POWERPC] Get default baud rate in udbg_scc
  [POWERPC] Fix zImage.coff on oldworld PowerMac
  [POWERPC] Fix xmon=off and cleanup xmon initialisation
  [POWERPC] Cleanup include/asm-powerpc/xmon.h
  [POWERPC] Update swim3 printk after blkdev.h change
  [POWERPC] Cell interrupt rework
  POWERPC: mpc82xx merge: board-specific/platform stuff(resend)
  POWERPC: 8272ads merge to powerpc: common stuff
  POWERPC: Added devicetree for mpc8272ads board
  [POWERPC] iSeries has no legacy I/O
  [POWERPC] implement BEGIN/END_FW_FTR_SECTION
  [POWERPC] iSeries does not need pcibios_fixup_resources
  ...
parents 18e6756a 9020fc96
......@@ -1440,6 +1440,258 @@ platforms are moved over to use the flattened-device-tree model.
descriptor-types-mask = <012b0ebf>;
};
h) Board Control and Status (BCSR)
Required properties:
- device_type : Should be "board-control"
- reg : Offset and length of the register set for the device
Example:
bcsr@f8000000 {
device_type = "board-control";
reg = <f8000000 8000>;
};
i) Freescale QUICC Engine module (QE)
This represents qe module that is installed on PowerQUICC II Pro.
Hopefully it will merge backward compatibility with CPM/CPM2.
Basically, it is a bus of devices, that could act more or less
as a complete entity (UCC, USB etc ). All of them should be siblings on
the "root" qe node, using the common properties from there.
The description below applies to the the qe of MPC8360 and
more nodes and properties would be extended in the future.
i) Root QE device
Required properties:
- device_type : should be "qe";
- model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
- reg : offset and length of the device registers.
- bus-frequency : the clock frequency for QUICC Engine.
Recommended properties
- brg-frequency : the internal clock source frequency for baud-rate
generators in Hz.
Example:
qe@e0100000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "qe";
model = "QE";
ranges = <0 e0100000 00100000>;
reg = <e0100000 480>;
brg-frequency = <0>;
bus-frequency = <179A7B00>;
}
ii) SPI (Serial Peripheral Interface)
Required properties:
- device_type : should be "spi".
- compatible : should be "fsl_spi".
- mode : the spi operation mode, it can be "cpu" or "qe".
- reg : Offset and length of the register set for the device
- interrupts : <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level
information for the interrupt. This should be encoded based on
the information in section 2) depending on the type of interrupt
controller you have.
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
Example:
spi@4c0 {
device_type = "spi";
compatible = "fsl_spi";
reg = <4c0 40>;
interrupts = <82 0>;
interrupt-parent = <700>;
mode = "cpu";
};
iii) USB (Universal Serial Bus Controller)
Required properties:
- device_type : should be "usb".
- compatible : could be "qe_udc" or "fhci-hcd".
- mode : the could be "host" or "slave".
- reg : Offset and length of the register set for the device
- interrupts : <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level
information for the interrupt. This should be encoded based on
the information in section 2) depending on the type of interrupt
controller you have.
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
Example(slave):
usb@6c0 {
device_type = "usb";
compatible = "qe_udc";
reg = <6c0 40>;
interrupts = <8b 0>;
interrupt-parent = <700>;
mode = "slave";
};
iv) UCC (Unified Communications Controllers)
Required properties:
- device_type : should be "network", "hldc", "uart", "transparent"
"bisync" or "atm".
- compatible : could be "ucc_geth" or "fsl_atm" and so on.
- model : should be "UCC".
- device-id : the ucc number(1-8), corresponding to UCCx in UM.
- reg : Offset and length of the register set for the device
- interrupts : <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level
information for the interrupt. This should be encoded based on
the information in section 2) depending on the type of interrupt
controller you have.
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
- pio-handle : The phandle for the Parallel I/O port configuration.
- rx-clock : represents the UCC receive clock source.
0x00 : clock source is disabled;
0x1~0x10 : clock source is BRG1~BRG16 respectively;
0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
- tx-clock: represents the UCC transmit clock source;
0x00 : clock source is disabled;
0x1~0x10 : clock source is BRG1~BRG16 respectively;
0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
Required properties for network device_type:
- mac-address : list of bytes representing the ethernet address.
- phy-handle : The phandle for the PHY connected to this controller.
Example:
ucc@2000 {
device_type = "network";
compatible = "ucc_geth";
model = "UCC";
device-id = <1>;
reg = <2000 200>;
interrupts = <a0 0>;
interrupt-parent = <700>;
mac-address = [ 00 04 9f 00 23 23 ];
rx-clock = "none";
tx-clock = "clk9";
phy-handle = <212000>;
pio-handle = <140001>;
};
v) Parallel I/O Ports
This node configures Parallel I/O ports for CPUs with QE support.
The node should reside in the "soc" node of the tree. For each
device that using parallel I/O ports, a child node should be created.
See the definition of the Pin configuration nodes below for more
information.
Required properties:
- device_type : should be "par_io".
- reg : offset to the register set and its length.
- num-ports : number of Parallel I/O ports
Example:
par_io@1400 {
reg = <1400 100>;
#address-cells = <1>;
#size-cells = <0>;
device_type = "par_io";
num-ports = <7>;
ucc_pin@01 {
......
};
vi) Pin configuration nodes
Required properties:
- linux,phandle : phandle of this node; likely referenced by a QE
device.
- pio-map : array of pin configurations. Each pin is defined by 6
integers. The six numbers are respectively: port, pin, dir,
open_drain, assignment, has_irq.
- port : port number of the pin; 0-6 represent port A-G in UM.
- pin : pin number in the port.
- dir : direction of the pin, should encode as follows:
0 = The pin is disabled
1 = The pin is an output
2 = The pin is an input
3 = The pin is I/O
- open_drain : indicates the pin is normal or wired-OR:
0 = The pin is actively driven as an output
1 = The pin is an open-drain driver. As an output, the pin is
driven active-low, otherwise it is three-stated.
- assignment : function number of the pin according to the Pin Assignment
tables in User Manual. Each pin can have up to 4 possible functions in
QE and two options for CPM.
- has_irq : indicates if the pin is used as source of exteral
interrupts.
Example:
ucc_pin@01 {
linux,phandle = <140001>;
pio-map = <
/* port pin dir open_drain assignment has_irq */
0 3 1 0 1 0 /* TxD0 */
0 4 1 0 1 0 /* TxD1 */
0 5 1 0 1 0 /* TxD2 */
0 6 1 0 1 0 /* TxD3 */
1 6 1 0 3 0 /* TxD4 */
1 7 1 0 1 0 /* TxD5 */
1 9 1 0 2 0 /* TxD6 */
1 a 1 0 2 0 /* TxD7 */
0 9 2 0 1 0 /* RxD0 */
0 a 2 0 1 0 /* RxD1 */
0 b 2 0 1 0 /* RxD2 */
0 c 2 0 1 0 /* RxD3 */
0 d 2 0 1 0 /* RxD4 */
1 1 2 0 2 0 /* RxD5 */
1 0 2 0 2 0 /* RxD6 */
1 4 2 0 2 0 /* RxD7 */
0 7 1 0 1 0 /* TX_EN */
0 8 1 0 1 0 /* TX_ER */
0 f 2 0 1 0 /* RX_DV */
0 10 2 0 1 0 /* RX_ER */
0 0 2 0 1 0 /* RX_CLK */
2 9 1 0 3 0 /* GTX_CLK - CLK10 */
2 8 2 0 1 0>; /* GTX125 - CLK9 */
};
vii) Multi-User RAM (MURAM)
Required properties:
- device_type : should be "muram".
- mode : the could be "host" or "slave".
- ranges : Should be defined as specified in 1) to describe the
translation of MURAM addresses.
- data-only : sub-node which defines the address area under MURAM
bus that can be allocated as data/parameter
Example:
muram@10000 {
device_type = "muram";
ranges = <0 00010000 0000c000>;
data-only@0{
reg = <0 c000>;
};
};
More devices will be defined as this spec matures.
......
......@@ -338,10 +338,6 @@ config PPC_MULTIPLATFORM
RS/6000 machine, an Apple machine, or a PReP, CHRP,
Maple or Cell-based machine.
config PPC_ISERIES
bool "IBM Legacy iSeries"
depends on PPC64
config EMBEDDED6xx
bool "Embedded 6xx/7xx/7xxx-based board"
depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
......@@ -355,6 +351,16 @@ config APUS
<http://linux-apus.sourceforge.net/>.
endchoice
config QUICC_ENGINE
bool
depends on PPC_MPC836x || PPC_MPC832x
default y
help
The QUICC Engine (QE) is a new generation of communications
coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
Selecting this option means that you wish to build a kernel
for a machine with a QE coprocessor.
config PPC_PSERIES
depends on PPC_MULTIPLATFORM && PPC64
bool "IBM pSeries & new (POWER5-based) iSeries"
......@@ -365,6 +371,10 @@ config PPC_PSERIES
select PPC_UDBG_16550
default y
config PPC_ISERIES
bool "IBM Legacy iSeries"
depends on PPC_MULTIPLATFORM && PPC64
config PPC_CHRP
bool "Common Hardware Reference Platform (CHRP) based machines"
depends on PPC_MULTIPLATFORM && PPC32
......@@ -594,6 +604,7 @@ endmenu
source arch/powerpc/platforms/embedded6xx/Kconfig
source arch/powerpc/platforms/4xx/Kconfig
source arch/powerpc/platforms/82xx/Kconfig
source arch/powerpc/platforms/83xx/Kconfig
source arch/powerpc/platforms/85xx/Kconfig
source arch/powerpc/platforms/86xx/Kconfig
......@@ -1058,6 +1069,8 @@ source "fs/Kconfig"
# XXX source "arch/ppc/8260_io/Kconfig"
source "arch/powerpc/sysdev/qe_lib/Kconfig"
source "arch/powerpc/platforms/iseries/Kconfig"
source "lib/Kconfig"
......
/*
* MPC8272 ADS Device Tree Source
*
* Copyright 2005 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/ {
model = "MPC8272ADS";
compatible = "MPC8260ADS";
#address-cells = <1>;
#size-cells = <1>;
linux,phandle = <100>;
cpus {
#cpus = <1>;
#address-cells = <1>;
#size-cells = <0>;
linux,phandle = <200>;
PowerPC,8272@0 {
device_type = "cpu";
reg = <0>;
d-cache-line-size = <20>; // 32 bytes
i-cache-line-size = <20>; // 32 bytes
d-cache-size = <4000>; // L1, 16K
i-cache-size = <4000>; // L1, 16K
timebase-frequency = <0>;
bus-frequency = <0>;
clock-frequency = <0>;
32-bit;
linux,phandle = <201>;
linux,boot-cpu;
};
};
interrupt-controller@f8200000 {
linux,phandle = <f8200000>;
#address-cells = <0>;
#interrupt-cells = <2>;
interrupt-controller;
reg = <f8200000 f8200004>;
built-in;
device_type = "pci-pic";
};
memory {
device_type = "memory";
linux,phandle = <300>;
reg = <00000000 4000000 f4500000 00000020>;
};
soc8272@f0000000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
ranges = < 0 0 2 00000000 f0000000 00053000>;
reg = <f0000000 0>;
mdio@0 {
device_type = "mdio";
compatible = "fs_enet";
reg = <0 0>;
linux,phandle = <24520>;
#address-cells = <1>;
#size-cells = <0>;
ethernet-phy@0 {
linux,phandle = <2452000>;
interrupt-parent = <10c00>;
interrupts = <19 1>;
reg = <0>;
bitbang = [ 12 12 13 02 02 01 ];
device_type = "ethernet-phy";
};
ethernet-phy@1 {
linux,phandle = <2452001>;
interrupt-parent = <10c00>;
interrupts = <19 1>;
bitbang = [ 12 12 13 02 02 01 ];
reg = <3>;
device_type = "ethernet-phy";
};
};
ethernet@24000 {
#address-cells = <1>;
#size-cells = <0>;
device_type = "network";
device-id = <2>;
compatible = "fs_enet";
model = "FCC";
reg = <11300 20 8400 100 11380 30>;
mac-address = [ 00 11 2F 99 43 54 ];
interrupts = <20 2>;
interrupt-parent = <10c00>;
phy-handle = <2452000>;
rx-clock = <13>;
tx-clock = <12>;
};
ethernet@25000 {
device_type = "network";
device-id = <3>;
compatible = "fs_enet";
model = "FCC";
reg = <11320 20 8500 100 113b0 30>;
mac-address = [ 00 11 2F 99 44 54 ];
interrupts = <21 2>;
interrupt-parent = <10c00>;
phy-handle = <2452001>;
rx-clock = <17>;
tx-clock = <18>;
};
cpm@f0000000 {
linux,phandle = <f0000000>;
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "cpm";
model = "CPM2";
ranges = <00000000 00000000 3ffff>;
reg = <10d80 3280>;
command-proc = <119c0>;
brg-frequency = <17D7840>;
cpm_clk = <BEBC200>;
scc@11a00 {
device_type = "serial";
compatible = "cpm_uart";
model = "SCC";
device-id = <2>;
reg = <11a00 20 8000 100>;
current-speed = <1c200>;
interrupts = <28 2>;
interrupt-parent = <10c00>;
clock-setup = <0 00ffffff>;
rx-clock = <1>;
tx-clock = <1>;
};
scc@11a60 {
device_type = "serial";
compatible = "cpm_uart";
model = "SCC";
device-id = <5>;
reg = <11a60 20 8300 100>;
current-speed = <1c200>;
interrupts = <2b 2>;
interrupt-parent = <10c00>;
clock-setup = <1b ffffff00>;
rx-clock = <4>;
tx-clock = <4>;
};
};
interrupt-controller@10c00 {
linux,phandle = <10c00>;
#address-cells = <0>;
#interrupt-cells = <2>;
interrupt-controller;
reg = <10c00 80>;
built-in;
device_type = "cpm-pic";
compatible = "CPM2";
};
pci@0500 {
linux,phandle = <0500>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
compatible = "8272";
device_type = "pci";
reg = <10430 4dc>;
clock-frequency = <3f940aa>;
interrupt-map-mask = <f800 0 0 7>;
interrupt-map = <
/* IDSEL 0x16 */
b000 0 0 1 f8200000 40 0
b000 0 0 2 f8200000 41 0
b000 0 0 3 f8200000 42 0
b000 0 0 4 f8200000 43 0
/* IDSEL 0x17 */
b800 0 0 1 f8200000 43 0
b800 0 0 2 f8200000 40 0
b800 0 0 3 f8200000 41 0
b800 0 0 4 f8200000 42 0
/* IDSEL 0x18 */
c000 0 0 1 f8200000 42 0
c000 0 0 2 f8200000 43 0
c000 0 0 3 f8200000 40 0
c000 0 0 4 f8200000 41 0>;
interrupt-parent = <10c00>;
interrupts = <14 3>;
bus-range = <0 0>;
ranges = <02000000 0 80000000 80000000 0 40000000
01000000 0 00000000 f6000000 0 02000000>;
};
/* May need to remove if on a part without crypto engine */
crypto@30000 {
device_type = "crypto";
model = "SEC2";
compatible = "talitos";
reg = <30000 10000>;
interrupts = <b 0>;
interrupt-parent = <10c00>;
num-channels = <4>;
channel-fifo-len = <18>;
exec-units-mask = <0000007e>;
/* desc mask is for rev1.x, we need runtime fixup for >=2.x */
descriptor-types-mask = <01010ebf>;
};
};
};
/*
* MPC8360E EMDS Device Tree Source
*
* Copyright 2006 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/*
/memreserve/ 00000000 1000000;
*/
/ {
model = "MPC8360EPB";
compatible = "MPC83xx";
#address-cells = <1>;
#size-cells = <1>;
linux,phandle = <100>;
cpus {
#cpus = <1>;
#address-cells = <1>;
#size-cells = <0>;
linux,phandle = <200>;
PowerPC,8360@0 {
device_type = "cpu";
reg = <0>;
d-cache-line-size = <20>; // 32 bytes
i-cache-line-size = <20>; // 32 bytes
d-cache-size = <8000>; // L1, 32K
i-cache-size = <8000>; // L1, 32K
timebase-frequency = <3EF1480>;
bus-frequency = <FBC5200>;
clock-frequency = <1F78A400>;
32-bit;
linux,phandle = <201>;
linux,boot-cpu;
};
};
memory {
device_type = "memory";
linux,phandle = <300>;
reg = <00000000 10000000>;
};
bcsr@f8000000 {
device_type = "board-control";
reg = <f8000000 8000>;
};
soc8360@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
ranges = <0 e0000000 00100000>;
reg = <e0000000 00000200>;
bus-frequency = <FBC5200>;
wdt@200 {
device_type = "watchdog";
compatible = "mpc83xx_wdt";
reg = <200 100>;
};
i2c@3000 {
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3000 100>;
interrupts = <e 8>;
interrupt-parent = <700>;
dfsrr;
};
i2c@3100 {
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3100 100>;
interrupts = <f 8>;
interrupt-parent = <700>;
dfsrr;
};
serial@4500 {
device_type = "serial";
compatible = "ns16550";
reg = <4500 100>;
clock-frequency = <FBC5200>;
interrupts = <9 8>;
interrupt-parent = <700>;
};
serial@4600 {
device_type = "serial";
compatible = "ns16550";
reg = <4600 100>;
clock-frequency = <FBC5200>;
interrupts = <a 8>;
interrupt-parent = <700>;
};
crypto@30000 {
device_type = "crypto";
model = "SEC2";
compatible = "talitos";
reg = <30000 10000>;
interrupts = <b 8>;
interrupt-parent = <700>;
num-channels = <4>;
channel-fifo-len = <18>;
exec-units-mask = <0000007e>;
/* desc mask is for rev1.x, we need runtime fixup for >=2.x */
descriptor-types-mask = <01010ebf>;
};
pci@8500 {
linux,phandle = <8500>;
interrupt-map-mask = <f800 0 0 7>;
interrupt-map = <
/* IDSEL 0x11 AD17 */
8800 0 0 1 700 14 8
8800 0 0 2 700 15 8
8800 0 0 3 700 16 8
8800 0 0 4 700 17 8
/* IDSEL 0x12 AD18 */
9000 0 0 1 700 16 8
9000 0 0 2 700 17 8
9000 0 0 3 700 14 8
9000 0 0 4 700 15 8
/* IDSEL 0x13 AD19 */
9800 0 0 1 700 17 8
9800 0 0 2 700 14 8
9800 0 0 3 700 15 8
9800 0 0 4 700 16 8
/* IDSEL 0x15 AD21*/
a800 0 0 1 700 14 8
a800 0 0 2 700 15 8
a800 0 0 3 700 16 8
a800 0 0 4 700 17 8
/* IDSEL 0x16 AD22*/
b000 0 0 1 700 17 8
b000 0 0 2 700 14 8
b000 0 0 3 700 15 8
b000 0 0 4 700 16 8
/* IDSEL 0x17 AD23*/
b800 0 0 1 700 16 8
b800 0 0 2 700 17 8
b800 0 0 3 700 14 8
b800 0 0 4 700 15 8
/* IDSEL 0x18 AD24*/
c000 0 0 1 700 15 8
c000 0 0 2 700 16 8
c000 0 0 3 700 17 8
c000 0 0 4 700 14 8>;
interrupt-parent = <700>;
interrupts = <42 8>;
bus-range = <0 0>;
ranges = <02000000 0 a0000000 a0000000 0 10000000
42000000 0 80000000 80000000 0 10000000
01000000 0 00000000 e2000000 0 00100000>;
clock-frequency = <3f940aa>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <8500 100>;
compatible = "83xx";
device_type = "pci";
};
pic@700 {
linux,phandle = <700>;
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <700 100>;
built-in;
device_type = "ipic";
};
par_io@1400 {
reg = <1400 100>;
device_type = "par_io";
num-ports = <7>;
ucc_pin@01 {
linux,phandle = <140001>;
pio-map = <
/* port pin dir open_drain assignment has_irq */
0 3 1 0 1 0 /* TxD0 */
0 4 1 0 1 0 /* TxD1 */
0 5 1 0 1 0 /* TxD2 */
0 6 1 0 1 0 /* TxD3 */
1 6 1 0 3 0 /* TxD4 */
1 7 1 0 1 0 /* TxD5 */
1 9 1 0 2 0 /* TxD6 */
1 a 1 0 2 0 /* TxD7 */
0 9 2 0 1 0 /* RxD0 */
0 a 2 0 1 0 /* RxD1 */
0 b 2 0 1 0 /* RxD2 */
0 c 2 0 1 0 /* RxD3 */
0 d 2 0 1 0 /* RxD4 */
1 1 2 0 2 0 /* RxD5 */
1 0 2 0 2 0 /* RxD6 */
1 4 2 0 2 0 /* RxD7 */
0 7 1 0 1 0 /* TX_EN */
0 8 1 0 1 0 /* TX_ER */
0 f 2 0 1 0 /* RX_DV */
0 10 2 0 1 0 /* RX_ER */
0 0 2 0 1 0 /* RX_CLK */
2 9 1 0 3 0 /* GTX_CLK - CLK10 */
2 8 2 0 1 0>; /* GTX125 - CLK9 */
};
ucc_pin@02 {
linux,phandle = <140002>;
pio-map = <
/* port pin dir open_drain assignment has_irq */
0 11 1 0 1 0 /* TxD0 */
0 12 1 0 1 0 /* TxD1 */
0 13 1 0 1 0 /* TxD2 */
0 14 1 0 1 0 /* TxD3 */
1 2 1 0 1 0 /* TxD4 */
1 3 1 0 2 0 /* TxD5 */
1 5 1 0 3 0 /* TxD6 */
1 8 1 0 3 0 /* TxD7 */
0 17 2 0 1 0 /* RxD0 */
0 18 2 0 1 0 /* RxD1 */
0 19 2 0 1 0 /* RxD2 */
0 1a 2 0 1 0 /* RxD3 */
0 1b 2 0 1 0 /* RxD4 */
1 c 2 0 2 0 /* RxD5 */
1 d 2 0 3 0 /* RxD6 */
1 b 2 0 2 0 /* RxD7 */
0 15 1 0 1 0 /* TX_EN */
0 16 1 0 1 0 /* TX_ER */
0 1d 2 0 1 0 /* RX_DV */
0 1e 2 0 1 0 /* RX_ER */
0 1f 2 0 1 0 /* RX_CLK */
2 2 1 0 2 0 /* GTX_CLK - CLK10 */
2 3 2 0 1 0 /* GTX125 - CLK4 */
0 1 3 0 2 0 /* MDIO */
0 2 1 0 1 0>; /* MDC */
};
};
};
qe@e0100000 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "qe";
model = "QE";
ranges = <0 e0100000 00100000>;
reg = <e0100000 480>;
brg-frequency = <0>;
bus-frequency = <179A7B00>;
muram@10000 {
device_type = "muram";
ranges = <0 00010000 0000c000>;
data-only@0{
reg = <0 c000>;
};
};
spi@4c0 {
device_type = "spi";
compatible = "fsl_spi";
reg = <4c0 40>;
interrupts = <2>;
interrupt-parent = <80>;
mode = "cpu";
};
spi@500 {
device_type = "spi";
compatible = "fsl_spi";
reg = <500 40>;
interrupts = <1>;
interrupt-parent = <80>;
mode = "cpu";
};
usb@6c0 {
device_type = "usb";
compatible = "qe_udc";
reg = <6c0 40 8B00 100>;
interrupts = <b>;
interrupt-parent = <80>;
mode = "slave";
};
ucc@2000 {
device_type = "network";
compatible = "ucc_geth";
model = "UCC";
device-id = <1>;
reg = <2000 200>;
interrupts = <20>;
interrupt-parent = <80>;
mac-address = [ 00 04 9f 00 23 23 ];
rx-clock = <0>;
tx-clock = <19>;
phy-handle = <212000>;
pio-handle = <140001>;
};
ucc@3000 {
device_type = "network";
compatible = "ucc_geth";
model = "UCC";
device-id = <2>;
reg = <3000 200>;
interrupts = <21>;
interrupt-parent = <80>;
mac-address = [ 00 11 22 33 44 55 ];
rx-clock = <0>;
tx-clock = <14>;
phy-handle = <212001>;
pio-handle = <140002>;
};
mdio@2120 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2120 18>;
device_type = "mdio";
compatible = "ucc_geth_phy";
ethernet-phy@00 {
linux,phandle = <212000>;
interrupt-parent = <700>;
interrupts = <11 2>;
reg = <0>;
device_type = "ethernet-phy";
interface = <6>; //ENET_1000_GMII
};
ethernet-phy@01 {
linux,phandle = <212001>;
interrupt-parent = <700>;
interrupts = <12 2>;
reg = <1>;
device_type = "ethernet-phy";
interface = <6>;
};
};
qeic@80 {
linux,phandle = <80>;
interrupt-controller;
device_type = "qeic";
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <80 80>;
built-in;
big-endian;
interrupts = <20 8 21 8>; //high:32 low:33
interrupt-parent = <700>;
};
};
};
......@@ -15,6 +15,7 @@ SECTIONS
{
*(.rodata*)
*(.data*)
*(__builtin_*)
*(.sdata*)
__got2_start = .;
*(.got2)
......
This diff is collapsed.
......@@ -763,10 +763,10 @@ struct cpu_spec cpu_specs[] = {
.cpu_setup = __setup_cpu_603,
.platform = "ppc603",
},
{ /* e300 (a 603e core, plus some) on 83xx */
{ /* e300c1 (a 603e core, plus some) on 83xx */
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00830000,
.cpu_name = "e300",
.cpu_name = "e300c1",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = COMMON_USER,
.icache_bsize = 32,
......@@ -774,6 +774,17 @@ struct cpu_spec cpu_specs[] = {
.cpu_setup = __setup_cpu_603,
.platform = "ppc603",
},
{ /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00840000,
.cpu_name = "e300c2",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
.platform = "ppc603",
},
{ /* default match, we assume split I/D cache & TB (non-601)... */
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
......
......@@ -27,10 +27,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cputable.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
#endif
#include <asm/firmware.h>
/*
* System calls.
......@@ -91,6 +88,7 @@ system_call_common:
ld r11,exception_marker@toc(r2)
std r11,-16(r9) /* "regshere" marker */
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
/* Hack for handling interrupts when soft-enabling on iSeries */
cmpdi cr1,r0,0x5555 /* syscall 0x5555 */
andi. r10,r12,MSR_PR /* from kernel */
......@@ -98,6 +96,7 @@ system_call_common:
beq hardware_interrupt_entry
lbz r10,PACAPROCENABLED(r13)
std r10,SOFTE(r1)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
mfmsr r11
ori r11,r11,MSR_EE
......@@ -462,6 +461,7 @@ _GLOBAL(ret_from_except_lite)
restore:
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
ld r5,SOFTE(r1)
cmpdi 0,r5,0
beq 4f
......@@ -480,6 +480,7 @@ restore:
b .ret_from_except_lite /* loop back and handle more */
4: stb r5,PACAPROCENABLED(r13)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
ld r3,_MSR(r1)
......@@ -538,18 +539,23 @@ do_work:
lwz r8,TI_PREEMPT(r9)
cmpwi cr1,r8,0
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
ld r0,SOFTE(r1)
cmpdi r0,0
#else
andi. r0,r3,MSR_EE
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
BEGIN_FW_FTR_SECTION
andi. r0,r3,MSR_EE
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
crandc eq,cr1*4+eq,eq
bne restore
/* here we are preempting the current task */
1:
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
li r0,1
stb r0,PACAPROCENABLED(r13)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
ori r10,r10,MSR_EE
mtmsrd r10,1 /* reenable interrupts */
......
......@@ -33,6 +33,7 @@
#include <asm/hvcall.h>
#include <asm/iseries/lpar_map.h>
#include <asm/thread_info.h>
#include <asm/firmware.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
......@@ -365,19 +366,28 @@ label##_iSeries: \
#ifdef DO_SOFT_DISABLE
#define DISABLE_INTS \
BEGIN_FW_FTR_SECTION; \
lbz r10,PACAPROCENABLED(r13); \
li r11,0; \
std r10,SOFTE(r1); \
mfmsr r10; \
stb r11,PACAPROCENABLED(r13); \
ori r10,r10,MSR_EE; \
mtmsrd r10,1
mtmsrd r10,1; \
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#define ENABLE_INTS \
BEGIN_FW_FTR_SECTION; \
lbz r10,PACAPROCENABLED(r13); \
mfmsr r11; \
std r10,SOFTE(r1); \
ori r11,r11,MSR_EE; \
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
BEGIN_FW_FTR_SECTION; \
ld r12,_MSR(r1); \
mfmsr r11; \
rlwimi r11,r12,0,MSR_EE; \
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
mtmsrd r11,1
#else /* hard enable/disable interrupts */
......@@ -1071,8 +1081,10 @@ _GLOBAL(slb_miss_realmode)
ld r3,PACA_EXSLB+EX_R3(r13)
lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
ld r11,PACALPPACAPTR(r13)
ld r11,LPPACASRR0(r11) /* get SRR0 value */
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_ISERIES */
mtlr r10
......@@ -1087,8 +1099,10 @@ _GLOBAL(slb_miss_realmode)
.machine pop
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_ISERIES */
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
......@@ -1301,6 +1315,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
cmpdi r3,0 /* see if hash_page succeeded */
#ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
/*
* If we had interrupts soft-enabled at the point where the
* DSI/ISI occurred, and an interrupt came in during hash_page,
......@@ -1321,12 +1336,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
ld r3,SOFTE(r1)
bl .local_irq_restore
b 11f
#else
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
BEGIN_FW_FTR_SECTION
beq fast_exception_return /* Return from exception on success */
ble- 12f /* Failure return from hash_page */
/* fall through */
#endif
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
/* Here we have a page fault that hash_page can't handle. */
_GLOBAL(handle_page_fault)
......@@ -1861,7 +1878,9 @@ _GLOBAL(__secondary_start)
LOAD_REG_ADDR(r3, .start_secondary_prolog)
LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
#ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
ori r4,r4,MSR_EE
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
......@@ -1986,6 +2005,7 @@ _STATIC(start_here_common)
*/
li r3,0
bl .do_cpu_ftr_fixups
bl .do_fw_ftr_fixups
/* ptr to current */
LOAD_REG_IMMEDIATE(r4, init_task)
......@@ -2000,11 +2020,13 @@ _STATIC(start_here_common)
/* Load up the kernel context */
5:
#ifdef DO_SOFT_DISABLE
BEGIN_FW_FTR_SECTION
li r5,0
stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
mfmsr r5
ori r5,r5,MSR_EE /* Hard Enabled */
mtmsrd r5
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
bl .start_kernel
......
......@@ -325,6 +325,52 @@ _GLOBAL(do_cpu_ftr_fixups)
isync
b 1b
/*
* do_fw_ftr_fixups - goes through the list of firmware feature fixups
* and writes nop's over sections of code that don't apply for this firmware.
* r3 = data offset (not changed)
*/
_GLOBAL(do_fw_ftr_fixups)
/* Get firmware features */
LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
sub r6,r6,r3
ld r4,0(r6)
/* Get the fixup table */
LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
sub r6,r6,r3
LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
sub r7,r7,r3
/* Do the fixup */
1: cmpld r6,r7
bgelr
addi r6,r6,32
ld r8,-32(r6) /* mask */
and r8,r8,r4
ld r9,-24(r6) /* value */
cmpld r8,r9
beq 1b
ld r8,-16(r6) /* section begin */
ld r9,-8(r6) /* section end */
subf. r9,r8,r9
beq 1b
/* write nops over the section of code */
/* todo: if large section, add a branch at the start of it */
srwi r9,r9,2
mtctr r9
sub r8,r8,r3
lis r0,0x60000000@h /* nop */
3: stw r0,0(r8)
BEGIN_FTR_SECTION
dcbst 0,r8 /* suboptimal, but simpler */
sync
icbi 0,r8
END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
addi r8,r8,4
bdnz 3b
sync /* additional sync needed on g4 */
isync
b 1b
#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
/*
* Do an IO access in real mode
......
......@@ -30,6 +30,7 @@
#include <asm/byteorder.h>
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#include <asm/firmware.h>
#ifdef DEBUG
#include <asm/udbg.h>
......@@ -209,7 +210,6 @@ void pcibios_free_controller(struct pci_controller *phb)
kfree(phb);
}
#ifndef CONFIG_PPC_ISERIES
void __devinit pcibios_claim_one_bus(struct pci_bus *b)
{
struct pci_dev *dev;
......@@ -238,10 +238,12 @@ static void __init pcibios_claim_of_setup(void)
{
struct pci_bus *b;
if (firmware_has_feature(FW_FEATURE_ISERIES))
return;
list_for_each_entry(b, &pci_root_buses, node)
pcibios_claim_one_bus(b);
}
#endif
#ifdef CONFIG_PPC_MULTIPLATFORM
static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
......@@ -554,9 +556,8 @@ static int __init pcibios_init(void)
*/
ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES))
iSeries_pcibios_init();
#endif
printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
......@@ -566,7 +567,7 @@ static int __init pcibios_init(void)
pci_bus_add_devices(hose->bus);
}
#ifndef CONFIG_PPC_ISERIES
if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
if (pci_probe_only)
pcibios_claim_of_setup();
else
......@@ -574,7 +575,7 @@ static int __init pcibios_init(void)
pci_assign_unassigned_resources() is able to work
correctly with [partially] allocated PCI tree. */
pci_assign_unassigned_resources();
#endif /* !CONFIG_PPC_ISERIES */
}
/* Call machine dependent final fixup */
if (ppc_md.pcibios_fixup)
......@@ -586,6 +587,7 @@ static int __init pcibios_init(void)
printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
#ifdef CONFIG_PPC_MULTIPLATFORM
if (!firmware_has_feature(FW_FEATURE_ISERIES))
/* map in PCI I/O space */
phbs_remap_io();
#endif
......@@ -637,13 +639,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
*/
int pci_domain_nr(struct pci_bus *bus)
{
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES))
return 0;
#else
else {
struct pci_controller *hose = pci_bus_to_host(bus);
return hose->global_number;
#endif
}
}
EXPORT_SYMBOL(pci_domain_nr);
......@@ -651,12 +653,12 @@ EXPORT_SYMBOL(pci_domain_nr);
/* Decide whether to display the domain number in /proc */
int pci_proc_domain(struct pci_bus *bus)
{
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES))
return 0;
#else
else {
struct pci_controller *hose = pci_bus_to_host(bus);
return hose->buid;
#endif
}
}
/*
......
......@@ -442,31 +442,6 @@ void __init smp_setup_cpu_maps(void)
}
#endif /* CONFIG_SMP */
int __initdata do_early_xmon;
#ifdef CONFIG_XMON
extern int xmon_no_auto_backtrace;
static int __init early_xmon(char *p)
{
/* ensure xmon is enabled */
if (p) {
if (strncmp(p, "on", 2) == 0)
xmon_init(1);
if (strncmp(p, "off", 3) == 0)
xmon_init(0);
if (strncmp(p, "nobt", 4) == 0)
xmon_no_auto_backtrace = 1;
if (strncmp(p, "early", 5) != 0)
return 0;
}
xmon_init(1);
do_early_xmon = 1;
return 0;
}
early_param("xmon", early_xmon);
#endif
static __init int add_pcspkr(void)
{
struct device_node *np;
......
......@@ -238,12 +238,11 @@ void __init setup_arch(char **cmdline_p)
smp_setup_cpu_maps();
#ifdef CONFIG_XMON_DEFAULT
xmon_init(1);
#endif
/* Register early console */
register_early_udbg_console();
xmon_setup();
#if defined(CONFIG_KGDB)
if (ppc_md.kgdb_map_scc)
ppc_md.kgdb_map_scc();
......@@ -280,9 +279,6 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) _edata;
init_mm.brk = klimit;
if (do_early_xmon)
debugger(NULL);
/* set up the bootmem stuff with available memory */
do_init_bootmem();
if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
......
......@@ -390,19 +390,15 @@ void __init setup_system(void)
*/
find_legacy_serial_ports();
/*
* Initialize xmon
*/
#ifdef CONFIG_XMON_DEFAULT
xmon_init(1);
#endif
/*
* Register early console
*/
register_early_udbg_console();
if (do_early_xmon)
debugger(NULL);
/*
* Initialize xmon
*/
xmon_setup();
check_smt_enabled();
smp_setup_cpu_maps();
......
......@@ -132,6 +132,14 @@ SECTIONS
*(__ftr_fixup)
__stop___ftr_fixup = .;
}
#ifdef CONFIG_PPC64
. = ALIGN(8);
__fw_ftr_fixup : {
__start___fw_ftr_fixup = .;
*(__fw_ftr_fixup)
__stop___fw_ftr_fixup = .;
}
#endif
. = ALIGN(PAGE_SIZE);
.init.ramfs : {
......
......@@ -63,32 +63,13 @@
#include <asm/iommu.h>
#include <asm/abs_addr.h>
#include <asm/vdso.h>
#include <asm/firmware.h>
#include "mmu_decl.h"
unsigned long ioremap_bot = IMALLOC_BASE;
static unsigned long phbs_io_bot = PHBS_IO_BASE;
#ifdef CONFIG_PPC_ISERIES
void __iomem *ioremap(unsigned long addr, unsigned long size)
{
return (void __iomem *)addr;
}
extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
unsigned long flags)
{
return (void __iomem *)addr;
}
void iounmap(volatile void __iomem *addr)
{
return;
}
#else
/*
* map_io_page currently only called by __ioremap
* map_io_page adds an entry to the ioremap page table
......@@ -161,6 +142,9 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
unsigned long pa, ea;
void __iomem *ret;
if (firmware_has_feature(FW_FEATURE_ISERIES))
return (void __iomem *)addr;
/*
* Choose an address to map it to.
* Once the imalloc system is running, we use it.
......@@ -255,6 +239,9 @@ void iounmap(volatile void __iomem *token)
{
void *addr;
if (firmware_has_feature(FW_FEATURE_ISERIES))
return;
if (!mem_init_done)
return;
......@@ -315,8 +302,6 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size)
return 0;
}
#endif
EXPORT_SYMBOL(ioremap);
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
......
......@@ -21,6 +21,7 @@
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/firmware.h>
/* void slb_allocate_realmode(unsigned long ea);
*
......@@ -183,6 +184,7 @@ slb_finish_load:
* dont have any LRU information to help us choose a slot.
*/
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
/*
* On iSeries, the "bolted" stack segment can be cast out on
* shared processor switch so we need to check for a miss on
......@@ -194,6 +196,7 @@ slb_finish_load:
li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */
cmpld r9,r3
beq 3f
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif /* CONFIG_PPC_ISERIES */
ld r10,PACASTABRR(r13)
......
menu "Platform support"
depends on PPC_82xx
choice
prompt "Machine Type"
default MPC82xx_ADS
config MPC82xx_ADS
bool "Freescale MPC82xx ADS"
select DEFAULT_UIMAGE
select PQ2ADS
select 8272
select 8260
select CPM2
select FSL_SOC
help
This option enables support for the MPC8272 ADS board
endchoice
endmenu
#
# Makefile for the PowerPC 82xx linux kernel.
#
obj-$(CONFIG_PPC_82xx) += mpc82xx.o
obj-$(CONFIG_MPC82xx_ADS) += mpc82xx_ads.o
#ifndef _PPC_KERNEL_M82XX_PCI_H
#define _PPC_KERNEL_M82XX_PCI_H
/*
* 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.
*/
#include <asm/m8260_pci.h>
#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET)
#ifndef _IO_BASE
#define _IO_BASE isa_io_base
#endif
#endif /* _PPC_KERNEL_M8260_PCI_H */
/*
* MPC82xx setup and early boot code plus other random bits.
*
* Author: Vitaly Bordug <vbordug@ru.mvista.com>
*
* Copyright (c) 2006 MontaVista Software, Inc.
*
* 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.
*/
#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/initrd.h>
#include <linux/module.h>
#include <linux/fsl_devices.h>
#include <linux/fs_uart_pd.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/atomic.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/bootinfo.h>
#include <asm/pci-bridge.h>
#include <asm/mpc8260.h>
#include <asm/irq.h>
#include <mm/mmu_decl.h>
#include <asm/prom.h>
#include <asm/cpm2.h>
#include <asm/udbg.h>
#include <asm/i8259.h>
#include <linux/fs_enet_pd.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/cpm2_pic.h>
#include "pq2ads_pd.h"
static int __init get_freq(char *name, unsigned long *val)
{
struct device_node *cpu;
unsigned int *fp;
int found = 0;
/* The cpu node should have timebase and clock frequency properties */
cpu = of_find_node_by_type(NULL, "cpu");
if (cpu) {
fp = (unsigned int *)get_property(cpu, name, NULL);
if (fp) {
found = 1;
*val = *fp++;
}
of_node_put(cpu);
}
return found;
}
void __init m82xx_calibrate_decr(void)
{
ppc_tb_freq = 125000000;
if (!get_freq("bus-frequency", &ppc_tb_freq)) {
printk(KERN_ERR "WARNING: Estimating decrementer frequency "
"(not found)\n");
}
ppc_tb_freq /= 4;
ppc_proc_freq = 1000000000;
if (!get_freq("clock-frequency", &ppc_proc_freq))
printk(KERN_ERR "WARNING: Estimating processor frequency"
"(not found)\n");
}
void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
{
uint pvid, svid, phid1;
uint memsize = total_memory;
pvid = mfspr(SPRN_PVR);
svid = mfspr(SPRN_SVR);
seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
seq_printf(m, "SVR\t\t: 0x%x\n", svid);
/* Display cpu Pll setting */
phid1 = mfspr(SPRN_HID1);
seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
/* Display the amount of memory */
seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
}
This diff is collapsed.
/*
* PQ2/mpc8260 board-specific stuff
*
* A collection of structures, addresses, and values associated with
* the Freescale MPC8260ADS/MPC8266ADS-PCI boards.
* Copied from the RPX-Classic and SBS8260 stuff.
*
* Author: Vitaly Bordug <vbordug@ru.mvista.com>
*
* Originally written by Dan Malek for Motorola MPC8260 family
*
* Copyright (c) 2001 Dan Malek <dan@embeddedalley.com>
* Copyright (c) 2006 MontaVista Software, Inc.
*
* 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.
*/
#ifdef __KERNEL__
#ifndef __MACH_ADS8260_DEFS
#define __MACH_ADS8260_DEFS
#include <linux/config.h>
#include <asm/ppcboot.h>
/* For our show_cpuinfo hooks. */
#define CPUINFO_VENDOR "Freescale Semiconductor"
#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
/* Backword-compatibility stuff for the drivers */
#define CPM_MAP_ADDR ((uint)0xf0000000)
#define CPM_IRQ_OFFSET 0
/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
* only on word boundaries.
* Not all are used (yet), or are interesting to us (yet).
*/
/* Things of interest in the CSR.
*/
#define BCSR0_LED0 ((uint)0x02000000) /* 0 == on */
#define BCSR0_LED1 ((uint)0x01000000) /* 0 == on */
#define BCSR1_FETHIEN ((uint)0x08000000) /* 0 == enable*/
#define BCSR1_FETH_RST ((uint)0x04000000) /* 0 == reset */
#define BCSR1_RS232_EN1 ((uint)0x02000000) /* 0 ==enable */
#define BCSR1_RS232_EN2 ((uint)0x01000000) /* 0 ==enable */
#define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable*/
#define BCSR3_FETH2_RS ((uint)0x80000000) /* 0 == reset */
/* cpm serial driver works with constants below */
#define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET)
#define SIU_INT_SMC2i ((uint)0x05+CPM_IRQ_OFFSET)
#define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET)
#define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET)
#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
void m82xx_pci_init_irq(void);
void mpc82xx_ads_show_cpuinfo(struct seq_file*);
void m82xx_calibrate_decr(void);
#endif /* __MACH_ADS8260_DEFS */
#endif /* __KERNEL__ */
......@@ -5,6 +5,13 @@ choice
prompt "Machine Type"
default MPC834x_SYS
config MPC832x_MDS
bool "Freescale MPC832x MDS"
select DEFAULT_UIMAGE
select QUICC_ENGINE
help
This option enables support for the MPC832x MDS evaluation board.
config MPC834x_SYS
bool "Freescale MPC834x SYS"
select DEFAULT_UIMAGE
......@@ -27,6 +34,12 @@ config MPC834x_ITX
endchoice
config PPC_MPC832x
bool
select PPC_UDBG_16550
select PPC_INDIRECT_PCI
default y if MPC832x_MDS
config MPC834x
bool
select PPC_UDBG_16550
......
/*
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
*
* Description:
* MPC832xE MDS board specific routines.
*
* 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.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/initrd.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/ipic.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include "mpc83xx.h"
#include "mpc832x_mds.h"
#undef DEBUG
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
#ifndef CONFIG_PCI
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
#endif
static u8 *bcsr_regs = NULL;
u8 *get_bcsr(void)
{
return bcsr_regs;
}
/* ************************************************************************
*
* Setup the architecture
*
*/
static void __init mpc832x_sys_setup_arch(void)
{
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("mpc832x_sys_setup_arch()", 0);
np = of_find_node_by_type(NULL, "cpu");
if (np != 0) {
unsigned int *fp =
(int *)get_property(np, "clock-frequency", NULL);
if (fp != 0)
loops_per_jiffy = *fp / HZ;
else
loops_per_jiffy = 50000000 / HZ;
of_node_put(np);
}
/* Map BCSR area */
np = of_find_node_by_name(NULL, "bcsr");
if (np != 0) {
struct resource res;
of_address_to_resource(np, 0, &res);
bcsr_regs = ioremap(res.start, res.end - res.start +1);
of_node_put(np);
}
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
ppc_md.pci_swizzle = common_swizzle;
ppc_md.pci_exclude_device = mpc83xx_exclude_device;
#endif
#ifdef CONFIG_QUICC_ENGINE
qe_reset();
if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
par_io_init(np);
of_node_put(np);
for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
par_io_of_config(np);
}
if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
!= NULL){
/* Reset the Ethernet PHY */
bcsr_regs[9] &= ~0x20;
udelay(1000);
bcsr_regs[9] |= 0x20;
iounmap(bcsr_regs);
of_node_put(np);
}
#endif /* CONFIG_QUICC_ENGINE */
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
ROOT_DEV = Root_RAM0;
else
#endif
#ifdef CONFIG_ROOT_NFS
ROOT_DEV = Root_NFS;
#else
ROOT_DEV = Root_HDA1;
#endif
}
void __init mpc832x_sys_init_IRQ(void)
{
struct device_node *np;
np = of_find_node_by_type(NULL, "ipic");
if (!np)
return;
ipic_init(np, 0);
/* Initialize the default interrupt mapping priorities,
* in case the boot rom changed something on us.
*/
ipic_set_default_priority();
of_node_put(np);
#ifdef CONFIG_QUICC_ENGINE
np = of_find_node_by_type(NULL, "qeic");
if (!np)
return;
qe_ic_init(np, 0);
of_node_put(np);
#endif /* CONFIG_QUICC_ENGINE */
}
#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
extern ulong ds1374_get_rtc_time(void);
extern int ds1374_set_rtc_time(ulong);
static int __init mpc832x_rtc_hookup(void)
{
struct timespec tv;
ppc_md.get_rtc_time = ds1374_get_rtc_time;
ppc_md.set_rtc_time = ds1374_set_rtc_time;
tv.tv_nsec = 0;
tv.tv_sec = (ppc_md.get_rtc_time) ();
do_settimeofday(&tv);
return 0;
}
late_initcall(mpc832x_rtc_hookup);
#endif
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
static int __init mpc832x_sys_probe(void)
{
char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
"model", NULL);
if (model == NULL)
return 0;
if (strcmp(model, "MPC8323EMDS"))
return 0;
DBG("%s found\n", model);
return 1;
}
define_machine(mpc832x_mds) {
.name = "MPC832x MDS",
.probe = mpc832x_sys_probe,
.setup_arch = mpc832x_sys_setup_arch,
.init_IRQ = mpc832x_sys_init_IRQ,
.get_irq = ipic_get_irq,
.restart = mpc83xx_restart,
.time_init = mpc83xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
/*
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
*
* Description:
* MPC832x MDS board specific header.
*
* 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.
*
*/
#ifndef __MACH_MPC832x_MDS_H__
#define __MACH_MPC832x_MDS_H__
extern u8 *get_bcsr(void);
#endif /* __MACH_MPC832x_MDS_H__ */
/*
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
*
* Author: Li Yang <LeoLi@freescale.com>
* Yin Olivia <Hong-hua.Yin@freescale.com>
*
* Description:
* MPC8360E MDS PB board specific routines.
*
* Changelog:
* Jun 21, 2006 Initial version
*
* 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.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/initrd.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/ipic.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include "mpc83xx.h"
#undef DEBUG
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
#ifndef CONFIG_PCI
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
#endif
static u8 *bcsr_regs = NULL;
u8 *get_bcsr(void)
{
return bcsr_regs;
}
/* ************************************************************************
*
* Setup the architecture
*
*/
static void __init mpc8360_sys_setup_arch(void)
{
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("mpc8360_sys_setup_arch()", 0);
np = of_find_node_by_type(NULL, "cpu");
if (np != 0) {
const unsigned int *fp =
get_property(np, "clock-frequency", NULL);
if (fp != 0)
loops_per_jiffy = *fp / HZ;
else
loops_per_jiffy = 50000000 / HZ;
of_node_put(np);
}
/* Map BCSR area */
np = of_find_node_by_name(NULL, "bcsr");
if (np != 0) {
struct resource res;
of_address_to_resource(np, 0, &res);
bcsr_regs = ioremap(res.start, res.end - res.start +1);
of_node_put(np);
}
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
ppc_md.pci_swizzle = common_swizzle;
ppc_md.pci_exclude_device = mpc83xx_exclude_device;
#endif
#ifdef CONFIG_QUICC_ENGINE
qe_reset();
if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
par_io_init(np);
of_node_put(np);
for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
par_io_of_config(np);
}
if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
!= NULL){
/* Reset the Ethernet PHY */
bcsr_regs[9] &= ~0x20;
udelay(1000);
bcsr_regs[9] |= 0x20;
iounmap(bcsr_regs);
of_node_put(np);
}
#endif /* CONFIG_QUICC_ENGINE */
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
ROOT_DEV = Root_RAM0;
else
#endif
#ifdef CONFIG_ROOT_NFS
ROOT_DEV = Root_NFS;
#else
ROOT_DEV = Root_HDA1;
#endif
}
void __init mpc8360_sys_init_IRQ(void)
{
struct device_node *np;
np = of_find_node_by_type(NULL, "ipic");
if (!np)
return;
ipic_init(np, 0);
/* Initialize the default interrupt mapping priorities,
* in case the boot rom changed something on us.
*/
ipic_set_default_priority();
of_node_put(np);
#ifdef CONFIG_QUICC_ENGINE
np = of_find_node_by_type(NULL, "qeic");
if (!np)
return;
qe_ic_init(np, 0);
of_node_put(np);
#endif /* CONFIG_QUICC_ENGINE */
}
#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
extern ulong ds1374_get_rtc_time(void);
extern int ds1374_set_rtc_time(ulong);
static int __init mpc8360_rtc_hookup(void)
{
struct timespec tv;
ppc_md.get_rtc_time = ds1374_get_rtc_time;
ppc_md.set_rtc_time = ds1374_set_rtc_time;
tv.tv_nsec = 0;
tv.tv_sec = (ppc_md.get_rtc_time) ();
do_settimeofday(&tv);
return 0;
}
late_initcall(mpc8360_rtc_hookup);
#endif
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
static int __init mpc8360_sys_probe(void)
{
char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
"model", NULL);
if (model == NULL)
return 0;
if (strcmp(model, "MPC8360EPB"))
return 0;
DBG("MPC8360EMDS-PB found\n");
return 1;
}
define_machine(mpc8360_sys) {
.name = "MPC8360E PB",
.probe = mpc8360_sys_probe,
.setup_arch = mpc8360_sys_setup_arch,
.init_IRQ = mpc8360_sys_init_IRQ,
.get_irq = ipic_get_irq,
.restart = mpc83xx_restart,
.time_init = mpc83xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
This diff is collapsed.
......@@ -2,48 +2,76 @@
#define ASM_CELL_PIC_H
#ifdef __KERNEL__
/*
* Mapping of IIC pending bits into per-node
* interrupt numbers.
* Mapping of IIC pending bits into per-node interrupt numbers.
*
* IRQ FF CC SS PP FF CC SS PP Description
* Interrupt numbers are in the range 0...0x1ff where the top bit
* (0x100) represent the source node. Only 2 nodes are supported with
* the current code though it's trivial to extend that if necessary using
* higher level bits
*
* 00-3f 80 02 +0 00 - 80 02 +0 3f South Bridge
* 00-3f 80 02 +b 00 - 80 02 +b 3f South Bridge
* 41-4a 80 00 +1 ** - 80 00 +a ** SPU Class 0
* 51-5a 80 01 +1 ** - 80 01 +a ** SPU Class 1
* 61-6a 80 02 +1 ** - 80 02 +a ** SPU Class 2
* 70-7f C0 ** ** 00 - C0 ** ** 0f IPI
* The bottom 8 bits are split into 2 type bits and 6 data bits that
* depend on the type:
*
* F flags
* C class
* S source
* P Priority
* + node number
* * don't care
* 00 (0x00 | data) : normal interrupt. data is (class << 4) | source
* 01 (0x40 | data) : IO exception. data is the exception number as
* defined by bit numbers in IIC_SR
* 10 (0x80 | data) : IPI. data is the IPI number (obtained from the priority)
* and node is always 0 (IPIs are per-cpu, their source is
* not relevant)
* 11 (0xc0 | data) : reserved
*
* A node consists of a Cell Broadband Engine and an optional
* south bridge device providing a maximum of 64 IRQs.
* The south bridge may be connected to either IOIF0
* or IOIF1.
* Each SPE is represented as three IRQ lines, one per
* interrupt class.
* 16 IRQ numbers are reserved for inter processor
* interruptions, although these are only used in the
* range of the first node.
* In addition, interrupt number 0x80000000 is defined as always invalid
* (that is the node field is expected to never extend to move than 23 bits)
*
* This scheme needs 128 IRQ numbers per BIF node ID,
* which means that with the total of 512 lines
* available, we can have a maximum of four nodes.
*/
enum {
IIC_IRQ_INVALID = 0xff,
IIC_IRQ_MAX = 0x3f,
IIC_IRQ_EXT_IOIF0 = 0x20,
IIC_IRQ_EXT_IOIF1 = 0x2b,
IIC_IRQ_IPI0 = 0x40,
IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */
IIC_SOURCE_COUNT = 0x50,
IIC_IRQ_INVALID = 0x80000000u,
IIC_IRQ_NODE_MASK = 0x100,
IIC_IRQ_NODE_SHIFT = 8,
IIC_IRQ_MAX = 0x1ff,
IIC_IRQ_TYPE_MASK = 0xc0,
IIC_IRQ_TYPE_NORMAL = 0x00,
IIC_IRQ_TYPE_IOEXC = 0x40,
IIC_IRQ_TYPE_IPI = 0x80,
IIC_IRQ_CLASS_SHIFT = 4,
IIC_IRQ_CLASS_0 = 0x00,
IIC_IRQ_CLASS_1 = 0x10,
IIC_IRQ_CLASS_2 = 0x20,
IIC_SOURCE_COUNT = 0x200,
/* Here are defined the various source/dest units. Avoid using those
* definitions if you can, they are mostly here for reference
*/
IIC_UNIT_SPU_0 = 0x4,
IIC_UNIT_SPU_1 = 0x7,
IIC_UNIT_SPU_2 = 0x3,
IIC_UNIT_SPU_3 = 0x8,
IIC_UNIT_SPU_4 = 0x2,
IIC_UNIT_SPU_5 = 0x9,
IIC_UNIT_SPU_6 = 0x1,
IIC_UNIT_SPU_7 = 0xa,
IIC_UNIT_IOC_0 = 0x0,
IIC_UNIT_IOC_1 = 0xb,
IIC_UNIT_THREAD_0 = 0xe, /* target only */
IIC_UNIT_THREAD_1 = 0xf, /* target only */
IIC_UNIT_IIC = 0xe, /* source only (IO exceptions) */
/* Base numbers for the external interrupts */
IIC_IRQ_EXT_IOIF0 =
IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_0,
IIC_IRQ_EXT_IOIF1 =
IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_1,
/* Base numbers for the IIC_ISR interrupts */
IIC_IRQ_IOEX_TMI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 63,
IIC_IRQ_IOEX_PMI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 62,
IIC_IRQ_IOEX_ATI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 61,
IIC_IRQ_IOEX_MATBFI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 60,
IIC_IRQ_IOEX_ELDI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 59,
/* Which bits in IIC_ISR are edge sensitive */
IIC_ISR_EDGE_MASK = 0x4ul,
};
extern void iic_init_IRQ(void);
......@@ -52,7 +80,6 @@ extern void iic_request_IPIs(void);
extern void iic_setup_cpu(void);
extern u8 iic_get_target_id(int cpu);
extern struct irq_host *iic_get_irq_host(int node);
extern void spider_init_IRQ(void);
......
......@@ -243,7 +243,6 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
const u32 *imap, *tmp;
int imaplen, intsize, unit;
struct device_node *iic;
struct irq_host *iic_host;
#if 0 /* Enable that when we have a way to retreive the node as well */
/* First, we check wether we have a real "interrupts" in the device
......@@ -289,11 +288,11 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
* the iic host from the iic OF node, but that way I'm still compatible
* with really really old old firmwares for which we don't have a node
*/
iic_host = iic_get_irq_host(pic->node_id);
if (iic_host == NULL)
return NO_IRQ;
/* Manufacture an IIC interrupt number of class 2 */
virq = irq_create_mapping(iic_host, 0x20 | unit);
virq = irq_create_mapping(NULL,
(pic->node_id << IIC_IRQ_NODE_SHIFT) |
(2 << IIC_IRQ_CLASS_SHIFT) |
unit);
if (virq == NO_IRQ)
printk(KERN_ERR "spider_pic: failed to map cascade !");
return virq;
......
......@@ -568,24 +568,23 @@ static void spu_unmap(struct spu *spu)
/* This function shall be abstracted for HV platforms */
static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
{
struct irq_host *host;
unsigned int isrc;
const u32 *tmp;
host = iic_get_irq_host(spu->node);
if (host == NULL)
return -ENODEV;
/* Get the interrupt source from the device-tree */
/* Get the interrupt source unit from the device-tree */
tmp = get_property(np, "isrc", NULL);
if (!tmp)
return -ENODEV;
spu->isrc = isrc = tmp[0];
isrc = tmp[0];
/* Add the node number */
isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
spu->isrc = isrc;
/* Now map interrupts of all 3 classes */
spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc);
spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc);
spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc);
spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
/* Right now, we only fail if class 2 failed */
return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
......
......@@ -262,14 +262,6 @@ void __init iSeries_pci_final_fixup(void)
mf_display_src(0xC9000200);
}
void pcibios_fixup_bus(struct pci_bus *PciBus)
{
}
void pcibios_fixup_resources(struct pci_dev *pdev)
{
}
/*
* Look down the chain to find the matching Device Device
*/
......
......@@ -649,15 +649,21 @@ static void iseries_dedicated_idle(void)
void __init iSeries_init_IRQ(void) { }
#endif
/*
* iSeries has no legacy IO, anything calling this function has to
* fail or bad things will happen
*/
static int iseries_check_legacy_ioport(unsigned int baseport)
{
return -ENODEV;
}
static int __init iseries_probe(void)
{
unsigned long root = of_get_flat_dt_root();
if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
return 0;
powerpc_firmware_features |= FW_FEATURE_ISERIES;
powerpc_firmware_features |= FW_FEATURE_LPAR;
hpte_init_iSeries();
return 1;
......@@ -680,6 +686,7 @@ define_machine(iseries) {
.calibrate_decr = generic_calibrate_decr,
.progress = iSeries_progress,
.probe = iseries_probe,
.check_legacy_ioport = iseries_check_legacy_ioport,
/* XXX Implement enable_pmcs for iSeries */
};
......@@ -687,6 +694,9 @@ void * __init iSeries_early_setup(void)
{
unsigned long phys_mem_size;
powerpc_firmware_features |= FW_FEATURE_ISERIES;
powerpc_firmware_features |= FW_FEATURE_LPAR;
iSeries_fixup_klimit();
/*
......
......@@ -111,8 +111,6 @@ void udbg_scc_init(int force_scc)
pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
/* Setup for 57600 8N1 */
if (ch == ch_a)
addr += 0x20;
sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
......@@ -125,9 +123,21 @@ void udbg_scc_init(int force_scc)
x = in_8(sccc);
out_8(sccc, 0x09); /* reset A or B side */
out_8(sccc, 0xc0);
/* If SCC was the OF output port, read the BRG value, else
* Setup for 57600 8N1
*/
if (ch_def != NULL) {
out_8(sccc, 13);
scc_inittab[1] = in_8(sccc);
out_8(sccc, 12);
scc_inittab[3] = in_8(sccc);
}
for (i = 0; i < sizeof(scc_inittab); ++i)
out_8(sccc, scc_inittab[i]);
udbg_putc = udbg_scc_putc;
udbg_getc = udbg_scc_getc;
udbg_getc_poll = udbg_scc_getc_poll;
......
......@@ -180,7 +180,7 @@ static void __init pseries_mpic_init_IRQ(void)
cascade_irq = irq_of_parse_and_map(cascade, 0);
if (cascade == NO_IRQ) {
printk(KERN_ERR "xics: failed to map cascade interrupt");
printk(KERN_ERR "mpic: failed to map cascade interrupt");
return;
}
......
......@@ -12,6 +12,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_PPC_TODC) += todc.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
ifeq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_I8259) += i8259.o
......
......@@ -147,7 +147,7 @@ static struct irq_chip cpm2_pic = {
.end = cpm2_end_irq,
};
int cpm2_get_irq(struct pt_regs *regs)
unsigned int cpm2_get_irq(struct pt_regs *regs)
{
int irq;
unsigned long bits;
......
......@@ -3,7 +3,7 @@
extern intctl_cpm2_t *cpm2_intctl;
extern int cpm2_get_irq(struct pt_regs *regs);
extern unsigned int cpm2_get_irq(struct pt_regs *regs);
extern void cpm2_pic_init(struct device_node*);
......
......@@ -37,6 +37,7 @@
#include <asm/cpm2.h>
extern void init_fcc_ioports(struct fs_platform_info*);
extern void init_scc_ioports(struct fs_uart_platform_info*);
static phys_addr_t immrbase = -1;
phys_addr_t get_immrbase(void)
......@@ -566,7 +567,7 @@ static int __init fs_enet_of_init(void)
struct resource r[4];
struct device_node *phy, *mdio;
struct fs_platform_info fs_enet_data;
const unsigned int *id, *phy_addr;
const unsigned int *id, *phy_addr, phy_irq;
const void *mac_addr;
const phandle *ph;
const char *model;
......@@ -588,6 +589,7 @@ static int __init fs_enet_of_init(void)
if (ret)
goto err;
r[2].name = fcc_regs_c;
fs_enet_data.fcc_regs_c = r[2].start;
r[3].start = r[3].end = irq_of_parse_and_map(np, 0);
r[3].flags = IORESOURCE_IRQ;
......@@ -620,6 +622,8 @@ static int __init fs_enet_of_init(void)
phy_addr = get_property(phy, "reg", NULL);
fs_enet_data.phy_addr = *phy_addr;
phy_irq = get_property(phy, "interrupts", NULL);
id = get_property(np, "device-id", NULL);
fs_enet_data.fs_no = *id;
strcpy(fs_enet_data.fs_type, model);
......@@ -637,6 +641,7 @@ static int __init fs_enet_of_init(void)
if (strstr(model, "FCC")) {
int fcc_index = *id - 1;
unsigned char* mdio_bb_prop;
fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
fs_enet_data.rx_ring = 32;
......@@ -652,6 +657,49 @@ static int __init fs_enet_of_init(void)
(u32)res.start, fs_enet_data.phy_addr);
fs_enet_data.bus_id = (char*)&bus_id[(*id)];
fs_enet_data.init_ioports = init_fcc_ioports;
mdio_bb_prop = get_property(phy, "bitbang", NULL);
if (mdio_bb_prop) {
struct platform_device *fs_enet_mdio_bb_dev;
struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
fs_enet_mdio_bb_dev =
platform_device_register_simple("fsl-bb-mdio",
i, NULL, 0);
memset(&fs_enet_mdio_bb_data, 0,
sizeof(struct fs_mii_bb_platform_info));
fs_enet_mdio_bb_data.mdio_dat.bit =
mdio_bb_prop[0];
fs_enet_mdio_bb_data.mdio_dir.bit =
mdio_bb_prop[1];
fs_enet_mdio_bb_data.mdc_dat.bit =
mdio_bb_prop[2];
fs_enet_mdio_bb_data.mdio_port =
mdio_bb_prop[3];
fs_enet_mdio_bb_data.mdc_port =
mdio_bb_prop[4];
fs_enet_mdio_bb_data.delay =
mdio_bb_prop[5];
fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
fs_enet_mdio_bb_data.irq[1] = -1;
fs_enet_mdio_bb_data.irq[2] = -1;
fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
fs_enet_mdio_bb_data.irq[31] = -1;
fs_enet_mdio_bb_data.mdio_dat.offset =
(u32)&cpm2_immr->im_ioport.iop_pdatc;
fs_enet_mdio_bb_data.mdio_dir.offset =
(u32)&cpm2_immr->im_ioport.iop_pdirc;
fs_enet_mdio_bb_data.mdc_dat.offset =
(u32)&cpm2_immr->im_ioport.iop_pdatc;
ret = platform_device_add_data(
fs_enet_mdio_bb_dev,
&fs_enet_mdio_bb_data,
sizeof(struct fs_mii_bb_platform_info));
if (ret)
goto unreg;
}
of_node_put(phy);
......
#
# QE Communication options
#
menu "QE Options"
depends on QUICC_ENGINE
config UCC_SLOW
bool "UCC Slow Protocols Support"
default n
select UCC
help
This option provides qe_lib support to UCC slow
protocols: UART, BISYNC, QMC
config UCC_FAST
bool "UCC Fast Protocols Support"
default n
select UCC
select UCC_SLOW
help
This option provides qe_lib support to UCC fast
protocols: HDLC, Ethernet, ATM, transparent
config UCC
bool
default y if UCC_FAST || UCC_SLOW
endmenu
#
# Makefile for the linux ppc-specific parts of QE
#
obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o
obj-$(CONFIG_UCC) += ucc.o
obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
obj-$(CONFIG_UCC_FAST) += ucc_fast.o
/*
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
*
* Authors: Shlomi Gridish <gridish@freescale.com>
* Li Yang <leoli@freescale.com>
* Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
*
* Description:
* General Purpose functions for the global management of the
* QUICC Engine (QE).
*
* 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.
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <asm/irq.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/immap_qe.h>
#include <asm/qe.h>
#include <asm/prom.h>
#include <asm/rheap.h>
static void qe_snums_init(void);
static void qe_muram_init(void);
static int qe_sdma_init(void);
static DEFINE_SPINLOCK(qe_lock);
/* QE snum state */
enum qe_snum_state {
QE_SNUM_STATE_USED,
QE_SNUM_STATE_FREE
};
/* QE snum */
struct qe_snum {
u8 num;
enum qe_snum_state state;
};
/* We allocate this here because it is used almost exclusively for
* the communication processor devices.
*/
struct qe_immap *qe_immr = NULL;
EXPORT_SYMBOL(qe_immr);
static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
static phys_addr_t qebase = -1;
phys_addr_t get_qe_base(void)
{
struct device_node *qe;
if (qebase != -1)
return qebase;
qe = of_find_node_by_type(NULL, "qe");
if (qe) {
unsigned int size;
const void *prop = get_property(qe, "reg", &size);
qebase = of_translate_address(qe, prop);
of_node_put(qe);
};
return qebase;
}
EXPORT_SYMBOL(get_qe_base);
void qe_reset(void)
{
if (qe_immr == NULL)
qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
qe_snums_init();
qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
QE_CR_PROTOCOL_UNSPECIFIED, 0);
/* Reclaim the MURAM memory for our use. */
qe_muram_init();
if (qe_sdma_init())
panic("sdma init failed!");
}
int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
{
unsigned long flags;
u8 mcn_shift = 0, dev_shift = 0;
spin_lock_irqsave(&qe_lock, flags);
if (cmd == QE_RESET) {
out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
} else {
if (cmd == QE_ASSIGN_PAGE) {
/* Here device is the SNUM, not sub-block */
dev_shift = QE_CR_SNUM_SHIFT;
} else if (cmd == QE_ASSIGN_RISC) {
/* Here device is the SNUM, and mcnProtocol is
* e_QeCmdRiscAssignment value */
dev_shift = QE_CR_SNUM_SHIFT;
mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
} else {
if (device == QE_CR_SUBBLOCK_USB)
mcn_shift = QE_CR_MCN_USB_SHIFT;
else
mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
}
out_be32(&qe_immr->cp.cecdr,
immrbar_virt_to_phys((void *)cmd_input));
out_be32(&qe_immr->cp.cecr,
(cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
mcn_protocol << mcn_shift));
}
/* wait for the QE_CR_FLG to clear */
while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG)
cpu_relax();
spin_unlock_irqrestore(&qe_lock, flags);
return 0;
}
EXPORT_SYMBOL(qe_issue_cmd);
/* Set a baud rate generator. This needs lots of work. There are
* 16 BRGs, which can be connected to the QE channels or output
* as clocks. The BRGs are in two different block of internal
* memory mapped space.
* The baud rate clock is the system clock divided by something.
* It was set up long ago during the initial boot phase and is
* is given to us.
* Baud rate clocks are zero-based in the driver code (as that maps
* to port numbers). Documentation uses 1-based numbering.
*/
static unsigned int brg_clk = 0;
unsigned int get_brg_clk(void)
{
struct device_node *qe;
if (brg_clk)
return brg_clk;
qe = of_find_node_by_type(NULL, "qe");
if (qe) {
unsigned int size;
const u32 *prop = get_property(qe, "brg-frequency", &size);
brg_clk = *prop;
of_node_put(qe);
};
return brg_clk;
}
/* This function is used by UARTS, or anything else that uses a 16x
* oversampled clock.
*/
void qe_setbrg(u32 brg, u32 rate)
{
volatile u32 *bp;
u32 divisor, tempval;
int div16 = 0;
bp = &qe_immr->brg.brgc1;
bp += brg;
divisor = (get_brg_clk() / rate);
if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
div16 = 1;
divisor /= 16;
}
tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
if (div16)
tempval |= QE_BRGC_DIV16;
out_be32(bp, tempval);
}
/* Initialize SNUMs (thread serial numbers) according to
* QE Module Control chapter, SNUM table
*/
static void qe_snums_init(void)
{
int i;
static const u8 snum_init[] = {
0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
0xD8, 0xD9, 0xE8, 0xE9,
};
for (i = 0; i < QE_NUM_OF_SNUM; i++) {
snums[i].num = snum_init[i];
snums[i].state = QE_SNUM_STATE_FREE;
}
}
int qe_get_snum(void)
{
unsigned long flags;
int snum = -EBUSY;
int i;
spin_lock_irqsave(&qe_lock, flags);
for (i = 0; i < QE_NUM_OF_SNUM; i++) {
if (snums[i].state == QE_SNUM_STATE_FREE) {
snums[i].state = QE_SNUM_STATE_USED;
snum = snums[i].num;
break;
}
}
spin_unlock_irqrestore(&qe_lock, flags);
return snum;
}
EXPORT_SYMBOL(qe_get_snum);
void qe_put_snum(u8 snum)
{
int i;
for (i = 0; i < QE_NUM_OF_SNUM; i++) {
if (snums[i].num == snum) {
snums[i].state = QE_SNUM_STATE_FREE;
break;
}
}
}
EXPORT_SYMBOL(qe_put_snum);
static int qe_sdma_init(void)
{
struct sdma *sdma = &qe_immr->sdma;
u32 sdma_buf_offset;
if (!sdma)
return -ENODEV;
/* allocate 2 internal temporary buffers (512 bytes size each) for
* the SDMA */
sdma_buf_offset = qe_muram_alloc(512 * 2, 64);
if (IS_MURAM_ERR(sdma_buf_offset))
return -ENOMEM;
out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK);
out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >>
QE_SDMR_CEN_SHIFT)));
return 0;
}
/*
* muram_alloc / muram_free bits.
*/
static DEFINE_SPINLOCK(qe_muram_lock);
/* 16 blocks should be enough to satisfy all requests
* until the memory subsystem goes up... */
static rh_block_t qe_boot_muram_rh_block[16];
static rh_info_t qe_muram_info;
static void qe_muram_init(void)
{
struct device_node *np;
u32 address;
u64 size;
unsigned int flags;
/* initialize the info header */
rh_init(&qe_muram_info, 1,
sizeof(qe_boot_muram_rh_block) /
sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block);
/* Attach the usable muram area */
/* XXX: This is a subset of the available muram. It
* varies with the processor and the microcode patches activated.
*/
if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) {
address = *of_get_address(np, 0, &size, &flags);
of_node_put(np);
rh_attach_region(&qe_muram_info,
(void *)address, (int)size);
}
}
/* This function returns an index into the MURAM area.
*/
u32 qe_muram_alloc(u32 size, u32 align)
{
void *start;
unsigned long flags;
spin_lock_irqsave(&qe_muram_lock, flags);
start = rh_alloc_align(&qe_muram_info, size, align, "QE");
spin_unlock_irqrestore(&qe_muram_lock, flags);
return (u32) start;
}
EXPORT_SYMBOL(qe_muram_alloc);
int qe_muram_free(u32 offset)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&qe_muram_lock, flags);
ret = rh_free(&qe_muram_info, (void *)offset);
spin_unlock_irqrestore(&qe_muram_lock, flags);
return ret;
}
EXPORT_SYMBOL(qe_muram_free);
/* not sure if this is ever needed */
u32 qe_muram_alloc_fixed(u32 offset, u32 size)
{
void *start;
unsigned long flags;
spin_lock_irqsave(&qe_muram_lock, flags);
start = rh_alloc_fixed(&qe_muram_info, (void *)offset, size, "commproc");
spin_unlock_irqrestore(&qe_muram_lock, flags);
return (u32) start;
}
EXPORT_SYMBOL(qe_muram_alloc_fixed);
void qe_muram_dump(void)
{
rh_dump(&qe_muram_info);
}
EXPORT_SYMBOL(qe_muram_dump);
void *qe_muram_addr(u32 offset)
{
return (void *)&qe_immr->muram[offset];
}
EXPORT_SYMBOL(qe_muram_addr);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2,6 +2,8 @@
* Routines providing a simple monitor for use on the PowerMac.
*
* Copyright (C) 1996-2005 Paul Mackerras.
* Copyright (C) 2001 PPC64 Team, IBM Corp
* Copyrignt (C) 2006 Michael Ellerman, IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -503,7 +505,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
mtmsr(msr); /* restore interrupt enable */
return cmd != 'X';
return cmd != 'X' && cmd != EOF;
}
int xmon(struct pt_regs *excp)
......@@ -2597,3 +2599,34 @@ static int __init setup_xmon_sysrq(void)
}
__initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
int __initdata xmon_early, xmon_off;
static int __init early_parse_xmon(char *p)
{
if (!p || strncmp(p, "early", 5) == 0) {
/* just "xmon" is equivalent to "xmon=early" */
xmon_init(1);
xmon_early = 1;
} else if (strncmp(p, "on", 2) == 0)
xmon_init(1);
else if (strncmp(p, "off", 3) == 0)
xmon_off = 1;
else if (strncmp(p, "nobt", 4) == 0)
xmon_no_auto_backtrace = 1;
else
return 1;
return 0;
}
early_param("xmon", early_parse_xmon);
void __init xmon_setup(void)
{
#ifdef CONFIG_XMON_DEFAULT
if (!xmon_off)
xmon_init(1);
#endif
if (xmon_early)
debugger(NULL);
}
......@@ -636,7 +636,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
intr = in_8(&sw->intr);
err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
if ((intr & ERROR_INTR) && fs->state != do_transfer)
printk(KERN_ERR "swim3_interrupt, state=%d, dir=%lx, intr=%x, err=%x\n",
printk(KERN_ERR "swim3_interrupt, state=%d, dir=%x, intr=%x, err=%x\n",
fs->state, rq_data_dir(fd_req), intr, err);
switch (fs->state) {
case locating:
......@@ -742,7 +742,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if ((stat & ACTIVE) == 0 || resid != 0) {
/* musta been an error */
printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid);
printk(KERN_ERR " state=%d, dir=%lx, intr=%x, err=%x\n",
printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n",
fs->state, rq_data_dir(fd_req), intr, err);
end_request(fd_req, 0);
fs->state = idle;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -91,10 +91,6 @@ DEBUGGER_BOILERPLATE(debugger_iabr_match)
DEBUGGER_BOILERPLATE(debugger_dabr_match)
DEBUGGER_BOILERPLATE(debugger_fault_handler)
#ifdef CONFIG_XMON
extern void xmon_init(int enable);
#endif
#else
static inline int debugger(struct pt_regs *regs) { return 0; }
static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
......
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