This patch adds new functionality to MV64x60 boot code. The changes are required to access DevCS windows registers and set PCI bus and devfn numbers for MV644x60 PCI/PCI-X interfaces.
Signed-off-by: Andrei Dolnikov <[EMAIL PROTECTED]> --- mv64x60.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mv64x60.h | 10 ++++++++ 2 files changed, 84 insertions(+) diff --git a/arch/powerpc/boot/mv64x60.c b/arch/powerpc/boot/mv64x60.c index d207a0b..787a124 100644 --- a/arch/powerpc/boot/mv64x60.c +++ b/arch/powerpc/boot/mv64x60.c @@ -32,6 +32,16 @@ #define MV64x60_CPU2MEM_3_BASE 0x0218 #define MV64x60_CPU2MEM_3_SIZE 0x0220 +#define MV64x60_DEV2MEM_WINDOWS 4 +#define MV64x60_DEV2MEM_0_BASE 0x0028 +#define MV64x60_DEV2MEM_0_SIZE 0x0030 +#define MV64x60_DEV2MEM_1_BASE 0x0228 +#define MV64x60_DEV2MEM_1_SIZE 0x0230 +#define MV64x60_DEV2MEM_2_BASE 0x0248 +#define MV64x60_DEV2MEM_2_SIZE 0x0250 +#define MV64x60_DEV2MEM_3_BASE 0x0038 +#define MV64x60_DEV2MEM_3_SIZE 0x0040 + #define MV64x60_ENET2MEM_BAR_ENABLE 0x2290 #define MV64x60_ENET2MEM_0_BASE 0x2200 #define MV64x60_ENET2MEM_0_SIZE 0x2204 @@ -219,6 +229,25 @@ static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = { }, }; +static struct mv64x60_mem_win mv64x60_devcs[MV64x60_DEV2MEM_WINDOWS] = { + [0] = { + .lo = MV64x60_DEV2MEM_0_BASE, + .size = MV64x60_DEV2MEM_0_SIZE, + }, + [1] = { + .lo = MV64x60_DEV2MEM_1_BASE, + .size = MV64x60_DEV2MEM_1_SIZE, + }, + [2] = { + .lo = MV64x60_DEV2MEM_2_BASE, + .size = MV64x60_DEV2MEM_2_SIZE, + }, + [3] = { + .lo = MV64x60_DEV2MEM_3_BASE, + .size = MV64x60_DEV2MEM_3_SIZE, + }, +}; + static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = { [0] = { .lo = MV64x60_ENET2MEM_0_BASE, @@ -567,6 +596,36 @@ void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi, out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size); } +/* Set PCI bus number for a PCI interface and force its devnum to 0 */ +void mv64x60_set_pci_bus(u8 *bridge_base, u8 hose, u32 bus, u32 devnum) +{ + u8 *pci_mode_reg, *p2p_cfg_reg; + u32 pci_mode, p2p_cfg; + u32 pci_cfg_offset; + + if (hose == 0) { + pci_mode_reg = bridge_base + MV64x60_PCI0_MODE; + p2p_cfg_reg = bridge_base + MV64x60_PCI0_P2P_CONF; + pci_cfg_offset = 0x64; + } else { + pci_mode_reg = bridge_base + MV64x60_PCI1_MODE; + p2p_cfg_reg = bridge_base + MV64x60_PCI1_P2P_CONF; + pci_cfg_offset = 0xe4; + } + + pci_mode = in_le32((u32*)pci_mode_reg) & MV64x60_PCI_MODE_MASK; + p2p_cfg = in_le32((u32*)p2p_cfg_reg); + + if (pci_mode == MV64x60_PCI_CONVENTIONAL_MODE) { + p2p_cfg &= 0xe0000000; + p2p_cfg |= (devnum << 24) | (bus << 16) | 0xff; + out_le32((u32*)p2p_cfg_reg, p2p_cfg); + } else + mv64x60_cfg_write(bridge_base, hose, (p2p_cfg >> 16) & 0xff, + PCI_DEVFN((p2p_cfg >> 24) & 0x1f, 0), + pci_cfg_offset, (devnum << 3) | (bus << 8)); +} + /* Read mem ctlr to get the amount of mem in system */ u32 mv64x60_get_mem_size(u8 *bridge_base) { @@ -586,6 +645,21 @@ u32 mv64x60_get_mem_size(u8 *bridge_base) return mem; } +/* Read a size of DEV_CS window */ +u32 mv64x60_get_devcs_size(u8 *bridge_base, u32 devcs) +{ + u32 enables, size = 0; + + enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf0; + + if (devcs < 4 && !(enables && (0x10 << devcs))) { + size = in_le32((u32*)(bridge_base + mv64x60_devcs[devcs].size)); + size = ((size & 0xffff) + 1) << 16; + } + + return size; +} + /* Get physical address of bridge's registers */ u8 *mv64x60_get_bridge_pbase(void) { diff --git a/arch/powerpc/boot/mv64x60.h b/arch/powerpc/boot/mv64x60.h index d0b29a7..a633d2e 100644 --- a/arch/powerpc/boot/mv64x60.h +++ b/arch/powerpc/boot/mv64x60.h @@ -12,6 +12,14 @@ #define MV64x60_CPU_BAR_ENABLE 0x0278 +#define MV64x60_PCI0_MODE 0x0d00 +#define MV64x60_PCI1_MODE 0x0d80 +#define MV64x60_PCI0_P2P_CONF 0x1d14 +#define MV64x60_PCI1_P2P_CONF 0x1d94 + +#define MV64x60_PCI_MODE_MASK 0x00000030 +#define MV64x60_PCI_CONVENTIONAL_MODE 0x00000000 + #define MV64x60_PCI_ACC_CNTL_ENABLE (1<<0) #define MV64x60_PCI_ACC_CNTL_REQ64 (1<<1) #define MV64x60_PCI_ACC_CNTL_SNOOP_NONE 0x00000000 @@ -57,7 +65,9 @@ void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose, void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi, u32 pci_base_lo, u32 cpu_base, u32 size, struct mv64x60_cpu2pci_win *offset_tbl); +void mv64x60_set_pci_bus(u8 *bridge_base, u8 hose, u32 bus, u32 devnum); u32 mv64x60_get_mem_size(u8 *bridge_base); +u32 mv64x60_get_devcs_size(u8 *bridge_base, u32 devcs); u8 *mv64x60_get_bridge_pbase(void); u8 *mv64x60_get_bridge_base(void); u8 mv64x60_is_coherent(void); _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev