Thread (30 messages) 30 messages, 6 authors, 2007-12-18
STALE6742d

[PATCH 2/5] PowerPC 74xx: Minor updates to MV64x60 boot code

From: Andrei Dolnikov <hidden>
Date: 2007-11-29 15:35:27
Subsystem: linux for powerpc (32-bit and 64-bit), the rest · Maintainers: Madhavan Srinivasan, Michael Ellerman, Linus Torvalds

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 <redacted>

---
 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);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help