aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2007-07-02 09:43:06 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-07-10 12:33:04 -0400
commit2db30150fe4fe309c57087c661209c9ea0b5c21b (patch)
tree7f327ade219e352f3819ab3cd8d53690b75a79d6 /arch/mips
parentbd43da8ff130caf31fff0482a75660507a26b641 (diff)
[MIPS] rbtx4938: Fix secondary PCIC and glue internal NICs
* Fix pci ops for secondary PCIC * Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero) * Use platform_device to provide ethernet addresses for internal NICs. (background: TX49XX SoCs include PCI NIC (TC35815 compatible) connected via its internal PCI bus, but the NIC's PROM interface is not connected to SEEPROM. So we must provide its ethernet address by another way.) * Check return value of early_read_config_word() Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/pci/ops-tx4938.c80
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c53
2 files changed, 70 insertions, 63 deletions
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
index 445007084515..a450c4062031 100644
--- a/arch/mips/pci/ops-tx4938.c
+++ b/arch/mips/pci/ops-tx4938.c
@@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = {
46 .flags = IORESOURCE_MEM 46 .flags = IORESOURCE_MEM
47}; 47};
48 48
49static int mkaddr(int bus, int dev_fn, int where, int *flagsp) 49static int mkaddr(int bus, int dev_fn, int where,
50 struct tx4938_pcic_reg *pcicptr)
50{ 51{
51 if (bus > 0) { 52 if (bus > 0) {
52 /* Type 1 configuration */ 53 /* Type 1 configuration */
53 tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | 54 pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
54 ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; 55 ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
55 } else { 56 } else {
56 if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) 57 if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
57 return -1; 58 return -1;
58 59
59 /* Type 0 configuration */ 60 /* Type 0 configuration */
60 tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | 61 pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
61 ((dev_fn & 0xff) << 0x08) | (where & 0xfc); 62 ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
62 } 63 }
63 /* clear M_ABORT and Disable M_ABORT Int. */ 64 /* clear M_ABORT and Disable M_ABORT Int. */
64 tx4938_pcicptr->pcistatus = 65 pcicptr->pcistatus =
65 (tx4938_pcicptr->pcistatus & 0x0000ffff) | 66 (pcicptr->pcistatus & 0x0000ffff) |
66 (PCI_STATUS_REC_MASTER_ABORT << 16); 67 (PCI_STATUS_REC_MASTER_ABORT << 16);
67 tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; 68 pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
68 69
69 return 0; 70 return 0;
70} 71}
71 72
72static int check_abort(int flags) 73static int check_abort(struct tx4938_pcic_reg *pcicptr)
73{ 74{
74 int code = PCIBIOS_SUCCESSFUL; 75 int code = PCIBIOS_SUCCESSFUL;
75 /* wait write cycle completion before checking error status */ 76 /* wait write cycle completion before checking error status */
76 while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) 77 while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
77 ; 78 ;
78 if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { 79 if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
79 tx4938_pcicptr->pcistatus = 80 pcicptr->pcistatus =
80 (tx4938_pcicptr-> 81 (pcicptr->
81 pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT 82 pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
82 << 16); 83 << 16);
83 tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; 84 pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
84 code = PCIBIOS_DEVICE_NOT_FOUND; 85 code = PCIBIOS_DEVICE_NOT_FOUND;
85 } 86 }
86 return code; 87 return code;
87} 88}
88 89
90extern struct pci_controller tx4938_pci_controller[];
91extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
92
93static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
94{
95 struct pci_controller *channel = bus->sysdata;
96 return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
97}
98
89static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, 99static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
90 int where, int size, u32 * val) 100 int where, int size, u32 * val)
91{ 101{
92 int flags, retval, dev, busno, func; 102 int retval, dev, busno, func;
103 struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
104 void __iomem *cfgdata =
105 (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
93 106
94 dev = PCI_SLOT(devfn); 107 dev = PCI_SLOT(devfn);
95 func = PCI_FUNC(devfn); 108 func = PCI_FUNC(devfn);
@@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
101 busno = 0; 114 busno = 0;
102 } 115 }
103 116
104 if (mkaddr(busno, devfn, where, &flags)) 117 if (mkaddr(busno, devfn, where, pcicptr))
105 return -1; 118 return -1;
106 119
107 switch (size) { 120 switch (size) {
108 case 1: 121 case 1:
109 *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
110#ifdef __BIG_ENDIAN 122#ifdef __BIG_ENDIAN
111 ((where & 3) ^ 3)); 123 cfgdata += (where & 3) ^ 3;
112#else 124#else
113 (where & 3)); 125 cfgdata += where & 3;
114#endif 126#endif
127 *val = __raw_readb(cfgdata);
115 break; 128 break;
116 case 2: 129 case 2:
117 *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
118#ifdef __BIG_ENDIAN 130#ifdef __BIG_ENDIAN
119 ((where & 3) ^ 2)); 131 cfgdata += (where & 2) ^ 2;
120#else 132#else
121 (where & 3)); 133 cfgdata += where & 2;
122#endif 134#endif
135 *val = __raw_readw(cfgdata);
123 break; 136 break;
124 case 4: 137 case 4:
125 *val = tx4938_pcicptr->g2pcfgdata; 138 *val = __raw_readl(cfgdata);
126 break; 139 break;
127 } 140 }
128 141
129 retval = check_abort(flags); 142 retval = check_abort(pcicptr);
130 if (retval == PCIBIOS_DEVICE_NOT_FOUND) 143 if (retval == PCIBIOS_DEVICE_NOT_FOUND)
131 *val = 0xffffffff; 144 *val = 0xffffffff;
132 145
@@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
136static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, 149static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
137 int size, u32 val) 150 int size, u32 val)
138{ 151{
139 int flags, dev, busno, func; 152 int dev, busno, func;
153 struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
154 void __iomem *cfgdata =
155 (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
140 156
141 busno = bus->number; 157 busno = bus->number;
142 dev = PCI_SLOT(devfn); 158 dev = PCI_SLOT(devfn);
@@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
149 busno = 0; 165 busno = 0;
150 } 166 }
151 167
152 if (mkaddr(busno, devfn, where, &flags)) 168 if (mkaddr(busno, devfn, where, pcicptr))
153 return -1; 169 return -1;
154 170
155 switch (size) { 171 switch (size) {
156 case 1: 172 case 1:
157 *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
158#ifdef __BIG_ENDIAN 173#ifdef __BIG_ENDIAN
159 ((where & 3) ^ 3)) = val; 174 cfgdata += (where & 3) ^ 3;
160#else 175#else
161 (where & 3)) = val; 176 cfgdata += where & 3;
162#endif 177#endif
178 __raw_writeb(val, cfgdata);
163 break; 179 break;
164 case 2: 180 case 2:
165 *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
166#ifdef __BIG_ENDIAN 181#ifdef __BIG_ENDIAN
167 ((where & 0x3) ^ 0x2)) = val; 182 cfgdata += (where & 2) ^ 2;
168#else 183#else
169 (where & 3)) = val; 184 cfgdata += where & 2;
170#endif 185#endif
186 __raw_writew(val, cfgdata);
171 break; 187 break;
172 case 4: 188 case 4:
173 tx4938_pcicptr->g2pcfgdata = val; 189 __raw_writel(val, cfgdata);
174 break; 190 break;
175 } 191 }
176 192
177 return check_abort(flags); 193 return check_abort(pcicptr);
178} 194}
179 195
180struct pci_ops tx4938_pci_ops = { 196struct pci_ops tx4938_pci_ops = {
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 361d89a81175..6ed39a5aea72 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -352,7 +352,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
352 static struct pci_dev dev; 352 static struct pci_dev dev;
353 static struct pci_bus bus; 353 static struct pci_bus bus;
354 354
355 dev.sysdata = (void *)hose; 355 dev.sysdata = bus.sysdata = hose;
356 dev.devfn = devfn; 356 dev.devfn = devfn;
357 bus.number = busnr; 357 bus.number = busnr;
358 bus.ops = hose->pci_ops; 358 bus.ops = hose->pci_ops;
@@ -385,8 +385,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu
385 printk("PCI: Checking 66MHz capabilities...\n"); 385 printk("PCI: Checking 66MHz capabilities...\n");
386 386
387 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { 387 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
388 early_read_config_word(hose, top_bus, current_bus, pci_devfn, 388 if (early_read_config_word(hose, top_bus, current_bus,
389 PCI_VENDOR_ID, &vid); 389 pci_devfn, PCI_VENDOR_ID,
390 &vid) != PCIBIOS_SUCCESSFUL)
391 continue;
390 392
391 if (vid == 0xffff) continue; 393 if (vid == 0xffff) continue;
392 394
@@ -463,7 +465,6 @@ static int __init tx4938_pcibios_init(void)
463 int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); 465 int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
464 466
465 PCIBIOS_MIN_IO = 0x00001000UL; 467 PCIBIOS_MIN_IO = 0x00001000UL;
466 PCIBIOS_MIN_MEM = 0x01000000UL;
467 468
468 mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); 469 mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
469 io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); 470 io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -578,18 +579,17 @@ arch_initcall(tx4938_pcibios_init);
578#define SRTC_CS 2 /* IOC */ 579#define SRTC_CS 2 /* IOC */
579 580
580#ifdef CONFIG_PCI 581#ifdef CONFIG_PCI
581static unsigned char rbtx4938_ethaddr[17];
582static int __init rbtx4938_ethaddr_init(void) 582static int __init rbtx4938_ethaddr_init(void)
583{ 583{
584 unsigned char dat[17];
584 unsigned char sum; 585 unsigned char sum;
585 int i; 586 int i;
586 587
587 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ 588 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
588 if (spi_eeprom_read(SEEPROM1_CS, 0, 589 if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
589 rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr)))
590 printk(KERN_ERR "seeprom: read error.\n"); 590 printk(KERN_ERR "seeprom: read error.\n");
591 else { 591 return -ENODEV;
592 unsigned char *dat = rbtx4938_ethaddr; 592 } else {
593 if (strcmp(dat, "MAC") != 0) 593 if (strcmp(dat, "MAC") != 0)
594 printk(KERN_WARNING "seeprom: bad signature.\n"); 594 printk(KERN_WARNING "seeprom: bad signature.\n");
595 for (i = 0, sum = 0; i < sizeof(dat); i++) 595 for (i = 0, sum = 0; i < sizeof(dat); i++)
@@ -597,31 +597,22 @@ static int __init rbtx4938_ethaddr_init(void)
597 if (sum) 597 if (sum)
598 printk(KERN_WARNING "seeprom: bad checksum.\n"); 598 printk(KERN_WARNING "seeprom: bad checksum.\n");
599 } 599 }
600 return 0; 600 for (i = 0; i < 2; i++) {
601} 601 unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i);
602device_initcall(rbtx4938_ethaddr_init); 602 unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */
603 603 struct platform_device *pdev;
604int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) 604 if (!(tx4938_ccfgptr->pcfg &
605{ 605 (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
606 struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; 606 continue;
607 int ch = 0; 607 pdev = platform_device_alloc("tc35815-mac", id);
608 608 if (!pdev ||
609 if (channel != &tx4938_pci_controller[1]) 609 platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
610 return -ENODEV; 610 platform_device_add(pdev))
611 /* TX4938 PCIC1 */ 611 platform_device_put(pdev);
612 switch (PCI_SLOT(dev->devfn)) {
613 case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
614 ch = 0;
615 break;
616 case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
617 ch = 1;
618 break;
619 default:
620 return -ENODEV;
621 } 612 }
622 memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6);
623 return 0; 613 return 0;
624} 614}
615device_initcall(rbtx4938_ethaddr_init);
625#endif /* CONFIG_PCI */ 616#endif /* CONFIG_PCI */
626 617
627static void __init rbtx4938_spi_setup(void) 618static void __init rbtx4938_spi_setup(void)