|
@@ -339,3 +339,165 @@ marvel_init_io7(struct io7 *io7)
|
|
|
* Get the Port 7 CSR pointer.
|
|
|
*/
|
|
|
io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Init this IO7's hoses.
|
|
|
+ */
|
|
|
+ for (i = 0; i < IO7_NUM_PORTS; i++) {
|
|
|
+ io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, i);
|
|
|
+ if (csrs->POx_CACHE_CTL.csr == 8) {
|
|
|
+ io7->ports[i].enabled = 1;
|
|
|
+ io7_init_hose(io7, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+marvel_io7_present(gct6_node *node)
|
|
|
+{
|
|
|
+ int pe;
|
|
|
+
|
|
|
+ if (node->type != GCT_TYPE_HOSE ||
|
|
|
+ node->subtype != GCT_SUBTYPE_IO_PORT_MODULE)
|
|
|
+ return;
|
|
|
+
|
|
|
+ pe = (node->id >> 8) & 0xff;
|
|
|
+ printk("Found an IO7 at PID %d\n", pe);
|
|
|
+
|
|
|
+ alloc_io7(pe);
|
|
|
+}
|
|
|
+
|
|
|
+static void __init
|
|
|
+marvel_find_console_vga_hose(void)
|
|
|
+{
|
|
|
+ u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
|
|
|
+
|
|
|
+ if (pu64[7] == 3) { /* TERM_TYPE == graphics */
|
|
|
+ struct pci_controller *hose = NULL;
|
|
|
+ int h = (pu64[30] >> 24) & 0xff; /* TERM_OUT_LOC, hose # */
|
|
|
+ struct io7 *io7;
|
|
|
+ int pid, port;
|
|
|
+
|
|
|
+ /* FIXME - encoding is going to have to change for Marvel
|
|
|
+ * since hose will be able to overflow a byte...
|
|
|
+ * need to fix this decode when the console
|
|
|
+ * changes its encoding
|
|
|
+ */
|
|
|
+ printk("console graphics is on hose %d (console)\n", h);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The console's hose numbering is:
|
|
|
+ *
|
|
|
+ * hose<n:2>: PID
|
|
|
+ * hose<1:0>: PORT
|
|
|
+ *
|
|
|
+ * We need to find the hose at that pid and port
|
|
|
+ */
|
|
|
+ pid = h >> 2;
|
|
|
+ port = h & 3;
|
|
|
+ if ((io7 = marvel_find_io7(pid)))
|
|
|
+ hose = io7->ports[port].hose;
|
|
|
+
|
|
|
+ if (hose) {
|
|
|
+ printk("Console graphics on hose %d\n", hose->index);
|
|
|
+ pci_vga_hose = hose;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+gct6_search_struct gct_wanted_node_list[] = {
|
|
|
+ { GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present },
|
|
|
+ { 0, 0, NULL }
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * In case the GCT is not complete, let the user specify PIDs with IO7s
|
|
|
+ * at boot time. Syntax is 'io7=a,b,c,...,n' where a-n are the PIDs (decimal)
|
|
|
+ * where IO7s are connected
|
|
|
+ */
|
|
|
+static int __init
|
|
|
+marvel_specify_io7(char *str)
|
|
|
+{
|
|
|
+ unsigned long pid;
|
|
|
+ struct io7 *io7;
|
|
|
+ char *pchar;
|
|
|
+
|
|
|
+ do {
|
|
|
+ pid = simple_strtoul(str, &pchar, 0);
|
|
|
+ if (pchar != str) {
|
|
|
+ printk("User-specified IO7 at PID %lu\n", pid);
|
|
|
+ io7 = alloc_io7(pid);
|
|
|
+ if (io7) marvel_init_io7(io7);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pchar == str) pchar++;
|
|
|
+ str = pchar;
|
|
|
+ } while(*str);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+__setup("io7=", marvel_specify_io7);
|
|
|
+
|
|
|
+void __init
|
|
|
+marvel_init_arch(void)
|
|
|
+{
|
|
|
+ struct io7 *io7;
|
|
|
+
|
|
|
+ /* With multiple PCI busses, we play with I/O as physical addrs. */
|
|
|
+ ioport_resource.end = ~0UL;
|
|
|
+
|
|
|
+ /* PCI DMA Direct Mapping is 1GB at 2GB. */
|
|
|
+ __direct_map_base = 0x80000000;
|
|
|
+ __direct_map_size = 0x40000000;
|
|
|
+
|
|
|
+ /* Parse the config tree. */
|
|
|
+ gct6_find_nodes(GCT_NODE_PTR(0), gct_wanted_node_list);
|
|
|
+
|
|
|
+ /* Init the io7s. */
|
|
|
+ for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); )
|
|
|
+ marvel_init_io7(io7);
|
|
|
+
|
|
|
+ /* Check for graphic console location (if any). */
|
|
|
+ marvel_find_console_vga_hose();
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+marvel_kill_arch(int mode)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * PCI Configuration Space access functions
|
|
|
+ *
|
|
|
+ * Configuration space addresses have the following format:
|
|
|
+ *
|
|
|
+ * |2 2 2 2|1 1 1 1|1 1 1 1|1 1
|
|
|
+ * |3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
|
|
|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
+ * |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|R|R|
|
|
|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
+ *
|
|
|
+ * n:24 reserved for hose base
|
|
|
+ * 23:16 bus number (8 bits = 128 possible buses)
|
|
|
+ * 15:11 Device number (5 bits)
|
|
|
+ * 10:8 function number
|
|
|
+ * 7:2 register number
|
|
|
+ *
|
|
|
+ * Notes:
|
|
|
+ * IO7 determines whether to use a type 0 or type 1 config cycle
|
|
|
+ * based on the bus number. Therefore the bus number must be set
|
|
|
+ * to 0 for the root bus on any hose.
|
|
|
+ *
|
|
|
+ * The function number selects which function of a multi-function device
|
|
|
+ * (e.g., SCSI and Ethernet).
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+static inline unsigned long
|
|
|
+build_conf_addr(struct pci_controller *hose, u8 bus,
|
|
|
+ unsigned int devfn, int where)
|
|
|
+{
|
|
|
+ return (hose->config_space_base | (bus << 16) | (devfn << 8) | where);
|
|
|
+}
|
|
|
+
|