ops-pmcmsp.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. /*
  2. * PMC-Sierra MSP board specific pci_ops
  3. *
  4. * Copyright 2001 MontaVista Software Inc.
  5. * Copyright 2005-2007 PMC-Sierra, Inc
  6. *
  7. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  8. *
  9. * Much of the code is derived from the original DDB5074 port by
  10. * Geert Uytterhoeven <geert@linux-m68k.org>
  11. *
  12. * This program is free software; you can redistribute it and/or modify it
  13. * under the terms of the GNU General Public License as published by the
  14. * Free Software Foundation; either version 2 of the License, or (at your
  15. * option) any later version.
  16. *
  17. */
  18. #define PCI_COUNTERS 1
  19. #include <linux/types.h>
  20. #include <linux/pci.h>
  21. #include <linux/interrupt.h>
  22. #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
  23. #include <linux/proc_fs.h>
  24. #include <linux/seq_file.h>
  25. #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
  26. #include <linux/kernel.h>
  27. #include <linux/init.h>
  28. #include <asm/byteorder.h>
  29. #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
  30. #include <asm/mipsmtregs.h>
  31. #endif
  32. #include <msp_prom.h>
  33. #include <msp_cic_int.h>
  34. #include <msp_pci.h>
  35. #include <msp_regs.h>
  36. #include <msp_regops.h>
  37. #define PCI_ACCESS_READ 0
  38. #define PCI_ACCESS_WRITE 1
  39. #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
  40. static char proc_init;
  41. extern struct proc_dir_entry *proc_bus_pci_dir;
  42. unsigned int pci_int_count[32];
  43. static void pci_proc_init(void);
  44. /*****************************************************************************
  45. *
  46. * FUNCTION: show_msp_pci_counts
  47. * _________________________________________________________________________
  48. *
  49. * DESCRIPTION: Prints the count of how many times each PCI
  50. * interrupt has asserted. Can be invoked by the
  51. * /proc filesystem.
  52. *
  53. * INPUTS: m - synthetic file construction data
  54. * v - iterator
  55. *
  56. * RETURNS: 0 or error
  57. *
  58. ****************************************************************************/
  59. static int show_msp_pci_counts(struct seq_file *m, void *v)
  60. {
  61. int i;
  62. unsigned int intcount, total = 0;
  63. for (i = 0; i < 32; ++i) {
  64. intcount = pci_int_count[i];
  65. if (intcount != 0) {
  66. seq_printf(m, "[%d] = %u\n", i, intcount);
  67. total += intcount;
  68. }
  69. }
  70. seq_printf(m, "total = %u\n", total);
  71. return 0;
  72. }
  73. /*****************************************************************************
  74. *
  75. * FUNCTION: gen_pci_cfg_wr_show
  76. * _________________________________________________________________________
  77. *
  78. * DESCRIPTION: Generates a configuration write cycle for debug purposes.
  79. * The IDSEL line asserted and location and data written are
  80. * immaterial. Just want to be able to prove that a
  81. * configuration write can be correctly generated on the
  82. * PCI bus. Intent is that this function by invocable from
  83. * the /proc filesystem.
  84. *
  85. * INPUTS: m - synthetic file construction data
  86. * v - iterator
  87. *
  88. * RETURNS: 0 or error
  89. *
  90. ****************************************************************************/
  91. static int gen_pci_cfg_wr_show(struct seq_file *m, void *v)
  92. {
  93. unsigned char where = 0; /* Write to static Device/Vendor ID */
  94. unsigned char bus_num = 0; /* Bus 0 */
  95. unsigned char dev_fn = 0xF; /* Arbitrary device number */
  96. u32 wr_data = 0xFF00AA00; /* Arbitrary data */
  97. struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
  98. unsigned long value;
  99. int intr;
  100. seq_puts(m, "PMC MSP PCI: Beginning\n");
  101. if (proc_init == 0) {
  102. pci_proc_init();
  103. proc_init = ~0;
  104. }
  105. seq_puts(m, "PMC MSP PCI: Before Cfg Wr\n");
  106. /*
  107. * Generate PCI Configuration Write Cycle
  108. */
  109. /* Clear cause register bits */
  110. preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
  111. /* Setup address that is to appear on PCI bus */
  112. preg->config_addr = BPCI_CFGADDR_ENABLE |
  113. (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
  114. (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
  115. (where & 0xFC);
  116. value = cpu_to_le32(wr_data);
  117. /* Launch the PCI configuration write cycle */
  118. *PCI_CONFIG_SPACE_REG = value;
  119. /*
  120. * Check if the PCI configuration cycle (rd or wr) succeeded, by
  121. * checking the status bits for errors like master or target abort.
  122. */
  123. intr = preg->if_status;
  124. seq_puts(m, "PMC MSP PCI: After Cfg Wr\n");
  125. return 0;
  126. }
  127. /*****************************************************************************
  128. *
  129. * FUNCTION: pci_proc_init
  130. * _________________________________________________________________________
  131. *
  132. * DESCRIPTION: Create entries in the /proc filesystem for debug access.
  133. *
  134. * INPUTS: none
  135. *
  136. * OUTPUTS: none
  137. *
  138. * RETURNS: none
  139. *
  140. ****************************************************************************/
  141. static void pci_proc_init(void)
  142. {
  143. proc_create_single("pmc_msp_pci_rd_cnt", 0, NULL, show_msp_pci_counts);
  144. proc_create_single("pmc_msp_pci_cfg_wr", 0, NULL, gen_pci_cfg_wr_show);
  145. }
  146. #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
  147. /*****************************************************************************
  148. *
  149. * STRUCT: pci_io_resource
  150. * _________________________________________________________________________
  151. *
  152. * DESCRIPTION: Defines the address range that pciauto() will use to
  153. * assign to the I/O BARs of PCI devices.
  154. *
  155. * Use the start and end addresses of the MSP7120 PCI Host
  156. * Controller I/O space, in the form that they appear on the
  157. * PCI bus AFTER MSP7120 has performed address translation.
  158. *
  159. * For I/O accesses, MSP7120 ignores OATRAN and maps I/O
  160. * accesses into the bottom 0xFFF region of address space,
  161. * so that is the range to put into the pci_io_resource
  162. * struct.
  163. *
  164. * In MSP4200, the start address was 0x04 instead of the
  165. * expected 0x00. Will just assume there was a good reason
  166. * for this!
  167. *
  168. * NOTES: Linux, by default, will assign I/O space to the lowest
  169. * region of address space. Since MSP7120 and Linux,
  170. * by default, have no offset in between how they map, the
  171. * io_offset element of pci_controller struct should be set
  172. * to zero.
  173. * ELEMENTS:
  174. * name - String used for a meaningful name.
  175. *
  176. * start - Start address of MSP7120's I/O space, as MSP7120 presents
  177. * the address on the PCI bus.
  178. *
  179. * end - End address of MSP7120's I/O space, as MSP7120 presents
  180. * the address on the PCI bus.
  181. *
  182. * flags - Attributes indicating the type of resource. In this case,
  183. * indicate I/O space.
  184. *
  185. ****************************************************************************/
  186. static struct resource pci_io_resource = {
  187. .name = "pci IO space",
  188. .start = 0x04,
  189. .end = 0x0FFF,
  190. .flags = IORESOURCE_IO /* I/O space */
  191. };
  192. /*****************************************************************************
  193. *
  194. * STRUCT: pci_mem_resource
  195. * _________________________________________________________________________
  196. *
  197. * DESCRIPTION: Defines the address range that pciauto() will use to
  198. * assign to the memory BARs of PCI devices.
  199. *
  200. * The .start and .end values are dependent upon how address
  201. * translation is performed by the OATRAN regiser.
  202. *
  203. * The values to use for .start and .end are the values
  204. * in the form they appear on the PCI bus AFTER MSP7120 has
  205. * performed OATRAN address translation.
  206. *
  207. * ELEMENTS:
  208. * name - String used for a meaningful name.
  209. *
  210. * start - Start address of MSP7120's memory space, as MSP7120 presents
  211. * the address on the PCI bus.
  212. *
  213. * end - End address of MSP7120's memory space, as MSP7120 presents
  214. * the address on the PCI bus.
  215. *
  216. * flags - Attributes indicating the type of resource. In this case,
  217. * indicate memory space.
  218. *
  219. ****************************************************************************/
  220. static struct resource pci_mem_resource = {
  221. .name = "pci memory space",
  222. .start = MSP_PCI_SPACE_BASE,
  223. .end = MSP_PCI_SPACE_END,
  224. .flags = IORESOURCE_MEM /* memory space */
  225. };
  226. /*****************************************************************************
  227. *
  228. * FUNCTION: bpci_interrupt
  229. * _________________________________________________________________________
  230. *
  231. * DESCRIPTION: PCI status interrupt handler. Updates the count of how
  232. * many times each status bit has been set, then clears
  233. * the status bits. If the appropriate macros are defined,
  234. * these counts can be viewed via the /proc filesystem.
  235. *
  236. * INPUTS: irq - unused
  237. * dev_id - unused
  238. * pt_regs - unused
  239. *
  240. * OUTPUTS: none
  241. *
  242. * RETURNS: PCIBIOS_SUCCESSFUL - success
  243. *
  244. ****************************************************************************/
  245. static irqreturn_t bpci_interrupt(int irq, void *dev_id)
  246. {
  247. struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
  248. unsigned int stat = preg->if_status;
  249. #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
  250. int i;
  251. for (i = 0; i < 32; ++i) {
  252. if ((1 << i) & stat)
  253. ++pci_int_count[i];
  254. }
  255. #endif /* PROC_FS && PCI_COUNTERS */
  256. /* printk("PCI ISR: Status=%08X\n", stat); */
  257. /* write to clear all asserted interrupts */
  258. preg->if_status = stat;
  259. return IRQ_HANDLED;
  260. }
  261. /*****************************************************************************
  262. *
  263. * FUNCTION: msp_pcibios_config_access
  264. * _________________________________________________________________________
  265. *
  266. * DESCRIPTION: Performs a PCI configuration access (rd or wr), then
  267. * checks that the access succeeded by querying MSP7120's
  268. * PCI status bits.
  269. *
  270. * INPUTS:
  271. * access_type - kind of PCI configuration cycle to perform
  272. * (read or write). Legal values are
  273. * PCI_ACCESS_WRITE and PCI_ACCESS_READ.
  274. *
  275. * bus - pointer to the bus number of the device to
  276. * be targeted for the configuration cycle.
  277. * The only element of the pci_bus structure
  278. * used is bus->number. This argument determines
  279. * if the configuration access will be Type 0 or
  280. * Type 1. Since MSP7120 assumes itself to be the
  281. * PCI Host, any non-zero bus->number generates
  282. * a Type 1 access.
  283. *
  284. * devfn - this is an 8-bit field. The lower three bits
  285. * specify the function number of the device to
  286. * be targeted for the configuration cycle, with
  287. * all three-bit combinations being legal. The
  288. * upper five bits specify the device number,
  289. * with legal values being 10 to 31.
  290. *
  291. * where - address within the Configuration Header
  292. * space to access.
  293. *
  294. * data - for write accesses, contains the data to
  295. * write.
  296. *
  297. * OUTPUTS:
  298. * data - for read accesses, contains the value read.
  299. *
  300. * RETURNS: PCIBIOS_SUCCESSFUL - success
  301. * -1 - access failure
  302. *
  303. ****************************************************************************/
  304. int msp_pcibios_config_access(unsigned char access_type,
  305. struct pci_bus *bus,
  306. unsigned int devfn,
  307. unsigned char where,
  308. u32 *data)
  309. {
  310. struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
  311. unsigned char bus_num = bus->number;
  312. unsigned char dev_fn = (unsigned char)devfn;
  313. unsigned long intr;
  314. unsigned long value;
  315. static char pciirqflag;
  316. int ret;
  317. #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
  318. unsigned int vpe_status;
  319. #endif
  320. #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
  321. if (proc_init == 0) {
  322. pci_proc_init();
  323. proc_init = ~0;
  324. }
  325. #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
  326. /*
  327. * Just the first time this function invokes, allocate
  328. * an interrupt line for PCI host status interrupts. The
  329. * allocation assigns an interrupt handler to the interrupt.
  330. */
  331. if (pciirqflag == 0) {
  332. ret = request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
  333. bpci_interrupt,
  334. IRQF_SHARED,
  335. "PMC MSP PCI Host",
  336. preg);
  337. if (ret != 0)
  338. return ret;
  339. pciirqflag = ~0;
  340. }
  341. #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
  342. vpe_status = dvpe();
  343. #endif
  344. /*
  345. * Clear PCI cause register bits.
  346. *
  347. * In Polo, the PCI Host had a dedicated DMA called the
  348. * Block Copy (not to be confused with the general purpose Block
  349. * Copy Engine block). There appear to have been special interrupts
  350. * for this Block Copy, called Block Copy 0 Fault (BC0F) and
  351. * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this
  352. * dedicated Block Copy block, so these two interrupts are now
  353. * marked reserved. In case the Block Copy is resurrected in a
  354. * future design, maintain the code that treats these two interrupts
  355. * specially.
  356. *
  357. * Write to clear all interrupts in the PCI status register, aside
  358. * from BC0F and BC1F.
  359. */
  360. preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
  361. /* Setup address that is to appear on PCI bus */
  362. preg->config_addr = BPCI_CFGADDR_ENABLE |
  363. (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
  364. (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
  365. (where & 0xFC);
  366. /* IF access is a PCI configuration write */
  367. if (access_type == PCI_ACCESS_WRITE) {
  368. value = cpu_to_le32(*data);
  369. *PCI_CONFIG_SPACE_REG = value;
  370. } else {
  371. /* ELSE access is a PCI configuration read */
  372. value = le32_to_cpu(*PCI_CONFIG_SPACE_REG);
  373. *data = value;
  374. }
  375. /*
  376. * Check if the PCI configuration cycle (rd or wr) succeeded, by
  377. * checking the status bits for errors like master or target abort.
  378. */
  379. intr = preg->if_status;
  380. /* Clear config access */
  381. preg->config_addr = 0;
  382. /* IF error occurred */
  383. if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) {
  384. /* Clear status bits */
  385. preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
  386. #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
  387. evpe(vpe_status);
  388. #endif
  389. return -1;
  390. }
  391. #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
  392. evpe(vpe_status);
  393. #endif
  394. return PCIBIOS_SUCCESSFUL;
  395. }
  396. /*****************************************************************************
  397. *
  398. * FUNCTION: msp_pcibios_read_config_byte
  399. * _________________________________________________________________________
  400. *
  401. * DESCRIPTION: Read a byte from PCI configuration address spac
  402. * Since the hardware can't address 8 bit chunks
  403. * directly, read a 32-bit chunk, then mask off extraneous
  404. * bits.
  405. *
  406. * INPUTS bus - structure containing attributes for the PCI bus
  407. * that the read is destined for.
  408. * devfn - device/function combination that the read is
  409. * destined for.
  410. * where - register within the Configuration Header space
  411. * to access.
  412. *
  413. * OUTPUTS val - read data
  414. *
  415. * RETURNS: PCIBIOS_SUCCESSFUL - success
  416. * -1 - read access failure
  417. *
  418. ****************************************************************************/
  419. static int
  420. msp_pcibios_read_config_byte(struct pci_bus *bus,
  421. unsigned int devfn,
  422. int where,
  423. u32 *val)
  424. {
  425. u32 data = 0;
  426. /*
  427. * If the config access did not complete normally (e.g., underwent
  428. * master abort) do the PCI compliant thing, which is to supply an
  429. * all ones value.
  430. */
  431. if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
  432. where, &data)) {
  433. *val = 0xFFFFFFFF;
  434. return -1;
  435. }
  436. *val = (data >> ((where & 3) << 3)) & 0x0ff;
  437. return PCIBIOS_SUCCESSFUL;
  438. }
  439. /*****************************************************************************
  440. *
  441. * FUNCTION: msp_pcibios_read_config_word
  442. * _________________________________________________________________________
  443. *
  444. * DESCRIPTION: Read a word (16 bits) from PCI configuration address space.
  445. * Since the hardware can't address 16 bit chunks
  446. * directly, read a 32-bit chunk, then mask off extraneous
  447. * bits.
  448. *
  449. * INPUTS bus - structure containing attributes for the PCI bus
  450. * that the read is destined for.
  451. * devfn - device/function combination that the read is
  452. * destined for.
  453. * where - register within the Configuration Header space
  454. * to access.
  455. *
  456. * OUTPUTS val - read data
  457. *
  458. * RETURNS: PCIBIOS_SUCCESSFUL - success
  459. * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
  460. * -1 - read access failure
  461. *
  462. ****************************************************************************/
  463. static int
  464. msp_pcibios_read_config_word(struct pci_bus *bus,
  465. unsigned int devfn,
  466. int where,
  467. u32 *val)
  468. {
  469. u32 data = 0;
  470. /* if (where & 1) */ /* Commented out non-compliant code.
  471. * Should allow word access to configuration
  472. * registers, with only exception being when
  473. * the word access would wrap around into
  474. * the next dword.
  475. */
  476. if ((where & 3) == 3) {
  477. *val = 0xFFFFFFFF;
  478. return PCIBIOS_BAD_REGISTER_NUMBER;
  479. }
  480. /*
  481. * If the config access did not complete normally (e.g., underwent
  482. * master abort) do the PCI compliant thing, which is to supply an
  483. * all ones value.
  484. */
  485. if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
  486. where, &data)) {
  487. *val = 0xFFFFFFFF;
  488. return -1;
  489. }
  490. *val = (data >> ((where & 3) << 3)) & 0x0ffff;
  491. return PCIBIOS_SUCCESSFUL;
  492. }
  493. /*****************************************************************************
  494. *
  495. * FUNCTION: msp_pcibios_read_config_dword
  496. * _________________________________________________________________________
  497. *
  498. * DESCRIPTION: Read a double word (32 bits) from PCI configuration
  499. * address space.
  500. *
  501. * INPUTS bus - structure containing attributes for the PCI bus
  502. * that the read is destined for.
  503. * devfn - device/function combination that the read is
  504. * destined for.
  505. * where - register within the Configuration Header space
  506. * to access.
  507. *
  508. * OUTPUTS val - read data
  509. *
  510. * RETURNS: PCIBIOS_SUCCESSFUL - success
  511. * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
  512. * -1 - read access failure
  513. *
  514. ****************************************************************************/
  515. static int
  516. msp_pcibios_read_config_dword(struct pci_bus *bus,
  517. unsigned int devfn,
  518. int where,
  519. u32 *val)
  520. {
  521. u32 data = 0;
  522. /* Address must be dword aligned. */
  523. if (where & 3) {
  524. *val = 0xFFFFFFFF;
  525. return PCIBIOS_BAD_REGISTER_NUMBER;
  526. }
  527. /*
  528. * If the config access did not complete normally (e.g., underwent
  529. * master abort) do the PCI compliant thing, which is to supply an
  530. * all ones value.
  531. */
  532. if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
  533. where, &data)) {
  534. *val = 0xFFFFFFFF;
  535. return -1;
  536. }
  537. *val = data;
  538. return PCIBIOS_SUCCESSFUL;
  539. }
  540. /*****************************************************************************
  541. *
  542. * FUNCTION: msp_pcibios_write_config_byte
  543. * _________________________________________________________________________
  544. *
  545. * DESCRIPTION: Write a byte to PCI configuration address space.
  546. * Since the hardware can't address 8 bit chunks
  547. * directly, a read-modify-write is performed.
  548. *
  549. * INPUTS bus - structure containing attributes for the PCI bus
  550. * that the write is destined for.
  551. * devfn - device/function combination that the write is
  552. * destined for.
  553. * where - register within the Configuration Header space
  554. * to access.
  555. * val - value to write
  556. *
  557. * OUTPUTS none
  558. *
  559. * RETURNS: PCIBIOS_SUCCESSFUL - success
  560. * -1 - write access failure
  561. *
  562. ****************************************************************************/
  563. static int
  564. msp_pcibios_write_config_byte(struct pci_bus *bus,
  565. unsigned int devfn,
  566. int where,
  567. u8 val)
  568. {
  569. u32 data = 0;
  570. /* read config space */
  571. if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
  572. where, &data))
  573. return -1;
  574. /* modify the byte within the dword */
  575. data = (data & ~(0xff << ((where & 3) << 3))) |
  576. (val << ((where & 3) << 3));
  577. /* write back the full dword */
  578. if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
  579. where, &data))
  580. return -1;
  581. return PCIBIOS_SUCCESSFUL;
  582. }
  583. /*****************************************************************************
  584. *
  585. * FUNCTION: msp_pcibios_write_config_word
  586. * _________________________________________________________________________
  587. *
  588. * DESCRIPTION: Write a word (16-bits) to PCI configuration address space.
  589. * Since the hardware can't address 16 bit chunks
  590. * directly, a read-modify-write is performed.
  591. *
  592. * INPUTS bus - structure containing attributes for the PCI bus
  593. * that the write is destined for.
  594. * devfn - device/function combination that the write is
  595. * destined for.
  596. * where - register within the Configuration Header space
  597. * to access.
  598. * val - value to write
  599. *
  600. * OUTPUTS none
  601. *
  602. * RETURNS: PCIBIOS_SUCCESSFUL - success
  603. * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
  604. * -1 - write access failure
  605. *
  606. ****************************************************************************/
  607. static int
  608. msp_pcibios_write_config_word(struct pci_bus *bus,
  609. unsigned int devfn,
  610. int where,
  611. u16 val)
  612. {
  613. u32 data = 0;
  614. /* Fixed non-compliance: if (where & 1) */
  615. if ((where & 3) == 3)
  616. return PCIBIOS_BAD_REGISTER_NUMBER;
  617. /* read config space */
  618. if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
  619. where, &data))
  620. return -1;
  621. /* modify the word within the dword */
  622. data = (data & ~(0xffff << ((where & 3) << 3))) |
  623. (val << ((where & 3) << 3));
  624. /* write back the full dword */
  625. if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
  626. where, &data))
  627. return -1;
  628. return PCIBIOS_SUCCESSFUL;
  629. }
  630. /*****************************************************************************
  631. *
  632. * FUNCTION: msp_pcibios_write_config_dword
  633. * _________________________________________________________________________
  634. *
  635. * DESCRIPTION: Write a double word (32-bits) to PCI configuration address
  636. * space.
  637. *
  638. * INPUTS bus - structure containing attributes for the PCI bus
  639. * that the write is destined for.
  640. * devfn - device/function combination that the write is
  641. * destined for.
  642. * where - register within the Configuration Header space
  643. * to access.
  644. * val - value to write
  645. *
  646. * OUTPUTS none
  647. *
  648. * RETURNS: PCIBIOS_SUCCESSFUL - success
  649. * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
  650. * -1 - write access failure
  651. *
  652. ****************************************************************************/
  653. static int
  654. msp_pcibios_write_config_dword(struct pci_bus *bus,
  655. unsigned int devfn,
  656. int where,
  657. u32 val)
  658. {
  659. /* check that address is dword aligned */
  660. if (where & 3)
  661. return PCIBIOS_BAD_REGISTER_NUMBER;
  662. /* perform write */
  663. if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
  664. where, &val))
  665. return -1;
  666. return PCIBIOS_SUCCESSFUL;
  667. }
  668. /*****************************************************************************
  669. *
  670. * FUNCTION: msp_pcibios_read_config
  671. * _________________________________________________________________________
  672. *
  673. * DESCRIPTION: Interface the PCI configuration read request with
  674. * the appropriate function, based on how many bytes
  675. * the read request is.
  676. *
  677. * INPUTS bus - structure containing attributes for the PCI bus
  678. * that the write is destined for.
  679. * devfn - device/function combination that the write is
  680. * destined for.
  681. * where - register within the Configuration Header space
  682. * to access.
  683. * size - in units of bytes, should be 1, 2, or 4.
  684. *
  685. * OUTPUTS val - value read, with any extraneous bytes masked
  686. * to zero.
  687. *
  688. * RETURNS: PCIBIOS_SUCCESSFUL - success
  689. * -1 - failure
  690. *
  691. ****************************************************************************/
  692. int
  693. msp_pcibios_read_config(struct pci_bus *bus,
  694. unsigned int devfn,
  695. int where,
  696. int size,
  697. u32 *val)
  698. {
  699. if (size == 1) {
  700. if (msp_pcibios_read_config_byte(bus, devfn, where, val)) {
  701. return -1;
  702. }
  703. } else if (size == 2) {
  704. if (msp_pcibios_read_config_word(bus, devfn, where, val)) {
  705. return -1;
  706. }
  707. } else if (size == 4) {
  708. if (msp_pcibios_read_config_dword(bus, devfn, where, val)) {
  709. return -1;
  710. }
  711. } else {
  712. *val = 0xFFFFFFFF;
  713. return -1;
  714. }
  715. return PCIBIOS_SUCCESSFUL;
  716. }
  717. /*****************************************************************************
  718. *
  719. * FUNCTION: msp_pcibios_write_config
  720. * _________________________________________________________________________
  721. *
  722. * DESCRIPTION: Interface the PCI configuration write request with
  723. * the appropriate function, based on how many bytes
  724. * the read request is.
  725. *
  726. * INPUTS bus - structure containing attributes for the PCI bus
  727. * that the write is destined for.
  728. * devfn - device/function combination that the write is
  729. * destined for.
  730. * where - register within the Configuration Header space
  731. * to access.
  732. * size - in units of bytes, should be 1, 2, or 4.
  733. * val - value to write
  734. *
  735. * OUTPUTS: none
  736. *
  737. * RETURNS: PCIBIOS_SUCCESSFUL - success
  738. * -1 - failure
  739. *
  740. ****************************************************************************/
  741. int
  742. msp_pcibios_write_config(struct pci_bus *bus,
  743. unsigned int devfn,
  744. int where,
  745. int size,
  746. u32 val)
  747. {
  748. if (size == 1) {
  749. if (msp_pcibios_write_config_byte(bus, devfn,
  750. where, (u8)(0xFF & val))) {
  751. return -1;
  752. }
  753. } else if (size == 2) {
  754. if (msp_pcibios_write_config_word(bus, devfn,
  755. where, (u16)(0xFFFF & val))) {
  756. return -1;
  757. }
  758. } else if (size == 4) {
  759. if (msp_pcibios_write_config_dword(bus, devfn, where, val)) {
  760. return -1;
  761. }
  762. } else {
  763. return -1;
  764. }
  765. return PCIBIOS_SUCCESSFUL;
  766. }
  767. /*****************************************************************************
  768. *
  769. * STRUCTURE: msp_pci_ops
  770. * _________________________________________________________________________
  771. *
  772. * DESCRIPTION: structure to abstract the hardware specific PCI
  773. * configuration accesses.
  774. *
  775. * ELEMENTS:
  776. * read - function for Linux to generate PCI Configuration reads.
  777. * write - function for Linux to generate PCI Configuration writes.
  778. *
  779. ****************************************************************************/
  780. struct pci_ops msp_pci_ops = {
  781. .read = msp_pcibios_read_config,
  782. .write = msp_pcibios_write_config
  783. };
  784. /*****************************************************************************
  785. *
  786. * STRUCTURE: msp_pci_controller
  787. * _________________________________________________________________________
  788. *
  789. * Describes the attributes of the MSP7120 PCI Host Controller
  790. *
  791. * ELEMENTS:
  792. * pci_ops - abstracts the hardware specific PCI configuration
  793. * accesses.
  794. *
  795. * mem_resource - address range pciauto() uses to assign to PCI device
  796. * memory BARs.
  797. *
  798. * mem_offset - offset between how MSP7120 outbound PCI memory
  799. * transaction addresses appear on the PCI bus and how Linux
  800. * wants to configure memory BARs of the PCI devices.
  801. * MSP7120 does nothing funky, so just set to zero.
  802. *
  803. * io_resource - address range pciauto() uses to assign to PCI device
  804. * I/O BARs.
  805. *
  806. * io_offset - offset between how MSP7120 outbound PCI I/O
  807. * transaction addresses appear on the PCI bus and how
  808. * Linux defaults to configure I/O BARs of the PCI devices.
  809. * MSP7120 maps outbound I/O accesses into the bottom
  810. * bottom 4K of PCI address space (and ignores OATRAN).
  811. * Since the Linux default is to configure I/O BARs to the
  812. * bottom 4K, no special offset is needed. Just set to zero.
  813. *
  814. ****************************************************************************/
  815. static struct pci_controller msp_pci_controller = {
  816. .pci_ops = &msp_pci_ops,
  817. .mem_resource = &pci_mem_resource,
  818. .mem_offset = 0,
  819. .io_map_base = MSP_PCI_IOSPACE_BASE,
  820. .io_resource = &pci_io_resource,
  821. .io_offset = 0
  822. };
  823. /*****************************************************************************
  824. *
  825. * FUNCTION: msp_pci_init
  826. * _________________________________________________________________________
  827. *
  828. * DESCRIPTION: Initialize the PCI Host Controller and register it with
  829. * Linux so Linux can seize control of the PCI bus.
  830. *
  831. ****************************************************************************/
  832. void __init msp_pci_init(void)
  833. {
  834. struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
  835. u32 id;
  836. /* Extract Device ID */
  837. id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12;
  838. /* Check if JTAG ID identifies MSP7120 */
  839. if (!MSP_HAS_PCI(id)) {
  840. printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id);
  841. goto no_pci;
  842. }
  843. /*
  844. * Enable flushing of the PCI-SDRAM queue upon a read
  845. * of the SDRAM's Memory Configuration Register.
  846. */
  847. *(unsigned long *)QFLUSH_REG_1 = 3;
  848. /* Configure PCI Host Controller. */
  849. preg->if_status = ~0; /* Clear cause register bits */
  850. preg->config_addr = 0; /* Clear config access */
  851. preg->oatran = MSP_PCI_OATRAN; /* PCI outbound addr translation */
  852. preg->if_mask = 0xF8BF87C0; /* Enable all PCI status interrupts */
  853. /* configure so inb(), outb(), and family are functional */
  854. set_io_port_base(MSP_PCI_IOSPACE_BASE);
  855. /* Tell Linux the details of the MSP7120 PCI Host Controller */
  856. register_pci_controller(&msp_pci_controller);
  857. return;
  858. no_pci:
  859. /* Disable PCI channel */
  860. printk(KERN_WARNING "PCI: no host PCI bus detected\n");
  861. }