pci-ftpci100.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /*
  2. * Support for Faraday Technology FTPC100 PCI Controller
  3. *
  4. * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
  5. *
  6. * Based on the out-of-tree OpenWRT patch for Cortina Gemini:
  7. * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
  8. * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
  9. * Based on SL2312 PCI controller code
  10. * Storlink (C) 2003
  11. */
  12. #include <linux/init.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/io.h>
  15. #include <linux/kernel.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_device.h>
  18. #include <linux/of_irq.h>
  19. #include <linux/of_pci.h>
  20. #include <linux/pci.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/slab.h>
  23. #include <linux/irqdomain.h>
  24. #include <linux/irqchip/chained_irq.h>
  25. #include <linux/bitops.h>
  26. #include <linux/irq.h>
  27. /*
  28. * Special configuration registers directly in the first few words
  29. * in I/O space.
  30. */
  31. #define PCI_IOSIZE 0x00
  32. #define PCI_PROT 0x04 /* AHB protection */
  33. #define PCI_CTRL 0x08 /* PCI control signal */
  34. #define PCI_SOFTRST 0x10 /* Soft reset counter and response error enable */
  35. #define PCI_CONFIG 0x28 /* PCI configuration command register */
  36. #define PCI_DATA 0x2C
  37. #define FARADAY_PCI_PMC 0x40 /* Power management control */
  38. #define FARADAY_PCI_PMCSR 0x44 /* Power management status */
  39. #define FARADAY_PCI_CTRL1 0x48 /* Control register 1 */
  40. #define FARADAY_PCI_CTRL2 0x4C /* Control register 2 */
  41. #define FARADAY_PCI_MEM1_BASE_SIZE 0x50 /* Memory base and size #1 */
  42. #define FARADAY_PCI_MEM2_BASE_SIZE 0x54 /* Memory base and size #2 */
  43. #define FARADAY_PCI_MEM3_BASE_SIZE 0x58 /* Memory base and size #3 */
  44. /* Bits 31..28 gives INTD..INTA status */
  45. #define PCI_CTRL2_INTSTS_SHIFT 28
  46. #define PCI_CTRL2_INTMASK_CMDERR BIT(27)
  47. #define PCI_CTRL2_INTMASK_PARERR BIT(26)
  48. /* Bits 25..22 masks INTD..INTA */
  49. #define PCI_CTRL2_INTMASK_SHIFT 22
  50. #define PCI_CTRL2_INTMASK_MABRT_RX BIT(21)
  51. #define PCI_CTRL2_INTMASK_TABRT_RX BIT(20)
  52. #define PCI_CTRL2_INTMASK_TABRT_TX BIT(19)
  53. #define PCI_CTRL2_INTMASK_RETRY4 BIT(18)
  54. #define PCI_CTRL2_INTMASK_SERR_RX BIT(17)
  55. #define PCI_CTRL2_INTMASK_PERR_RX BIT(16)
  56. /* Bit 15 reserved */
  57. #define PCI_CTRL2_MSTPRI_REQ6 BIT(14)
  58. #define PCI_CTRL2_MSTPRI_REQ5 BIT(13)
  59. #define PCI_CTRL2_MSTPRI_REQ4 BIT(12)
  60. #define PCI_CTRL2_MSTPRI_REQ3 BIT(11)
  61. #define PCI_CTRL2_MSTPRI_REQ2 BIT(10)
  62. #define PCI_CTRL2_MSTPRI_REQ1 BIT(9)
  63. #define PCI_CTRL2_MSTPRI_REQ0 BIT(8)
  64. /* Bits 7..4 reserved */
  65. /* Bits 3..0 TRDYW */
  66. /*
  67. * Memory configs:
  68. * Bit 31..20 defines the PCI side memory base
  69. * Bit 19..16 (4 bits) defines the size per below
  70. */
  71. #define FARADAY_PCI_MEMBASE_MASK 0xfff00000
  72. #define FARADAY_PCI_MEMSIZE_1MB 0x0
  73. #define FARADAY_PCI_MEMSIZE_2MB 0x1
  74. #define FARADAY_PCI_MEMSIZE_4MB 0x2
  75. #define FARADAY_PCI_MEMSIZE_8MB 0x3
  76. #define FARADAY_PCI_MEMSIZE_16MB 0x4
  77. #define FARADAY_PCI_MEMSIZE_32MB 0x5
  78. #define FARADAY_PCI_MEMSIZE_64MB 0x6
  79. #define FARADAY_PCI_MEMSIZE_128MB 0x7
  80. #define FARADAY_PCI_MEMSIZE_256MB 0x8
  81. #define FARADAY_PCI_MEMSIZE_512MB 0x9
  82. #define FARADAY_PCI_MEMSIZE_1GB 0xa
  83. #define FARADAY_PCI_MEMSIZE_2GB 0xb
  84. #define FARADAY_PCI_MEMSIZE_SHIFT 16
  85. /*
  86. * The DMA base is set to 0x0 for all memory segments, it reflects the
  87. * fact that the memory of the host system starts at 0x0.
  88. */
  89. #define FARADAY_PCI_DMA_MEM1_BASE 0x00000000
  90. #define FARADAY_PCI_DMA_MEM2_BASE 0x00000000
  91. #define FARADAY_PCI_DMA_MEM3_BASE 0x00000000
  92. /* Defines for PCI configuration command register */
  93. #define PCI_CONF_ENABLE BIT(31)
  94. #define PCI_CONF_WHERE(r) ((r) & 0xFC)
  95. #define PCI_CONF_BUS(b) (((b) & 0xFF) << 16)
  96. #define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11)
  97. #define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8)
  98. /**
  99. * struct faraday_pci_variant - encodes IP block differences
  100. * @cascaded_irq: this host has cascaded IRQs from an interrupt controller
  101. * embedded in the host bridge.
  102. */
  103. struct faraday_pci_variant {
  104. bool cascaded_irq;
  105. };
  106. struct faraday_pci {
  107. struct device *dev;
  108. void __iomem *base;
  109. struct irq_domain *irqdomain;
  110. struct pci_bus *bus;
  111. };
  112. static int faraday_res_to_memcfg(resource_size_t mem_base,
  113. resource_size_t mem_size, u32 *val)
  114. {
  115. u32 outval;
  116. switch (mem_size) {
  117. case SZ_1M:
  118. outval = FARADAY_PCI_MEMSIZE_1MB;
  119. break;
  120. case SZ_2M:
  121. outval = FARADAY_PCI_MEMSIZE_2MB;
  122. break;
  123. case SZ_4M:
  124. outval = FARADAY_PCI_MEMSIZE_4MB;
  125. break;
  126. case SZ_8M:
  127. outval = FARADAY_PCI_MEMSIZE_8MB;
  128. break;
  129. case SZ_16M:
  130. outval = FARADAY_PCI_MEMSIZE_16MB;
  131. break;
  132. case SZ_32M:
  133. outval = FARADAY_PCI_MEMSIZE_32MB;
  134. break;
  135. case SZ_64M:
  136. outval = FARADAY_PCI_MEMSIZE_64MB;
  137. break;
  138. case SZ_128M:
  139. outval = FARADAY_PCI_MEMSIZE_128MB;
  140. break;
  141. case SZ_256M:
  142. outval = FARADAY_PCI_MEMSIZE_256MB;
  143. break;
  144. case SZ_512M:
  145. outval = FARADAY_PCI_MEMSIZE_512MB;
  146. break;
  147. case SZ_1G:
  148. outval = FARADAY_PCI_MEMSIZE_1GB;
  149. break;
  150. case SZ_2G:
  151. outval = FARADAY_PCI_MEMSIZE_2GB;
  152. break;
  153. default:
  154. return -EINVAL;
  155. }
  156. outval <<= FARADAY_PCI_MEMSIZE_SHIFT;
  157. /* This is probably not good */
  158. if (mem_base & ~(FARADAY_PCI_MEMBASE_MASK))
  159. pr_warn("truncated PCI memory base\n");
  160. /* Translate to bridge side address space */
  161. outval |= (mem_base & FARADAY_PCI_MEMBASE_MASK);
  162. pr_debug("Translated pci base @%pap, size %pap to config %08x\n",
  163. &mem_base, &mem_size, outval);
  164. *val = outval;
  165. return 0;
  166. }
  167. static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,
  168. int config, int size, u32 *value)
  169. {
  170. struct faraday_pci *p = bus->sysdata;
  171. writel(PCI_CONF_BUS(bus->number) |
  172. PCI_CONF_DEVICE(PCI_SLOT(fn)) |
  173. PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
  174. PCI_CONF_WHERE(config) |
  175. PCI_CONF_ENABLE,
  176. p->base + PCI_CONFIG);
  177. *value = readl(p->base + PCI_DATA);
  178. if (size == 1)
  179. *value = (*value >> (8 * (config & 3))) & 0xFF;
  180. else if (size == 2)
  181. *value = (*value >> (8 * (config & 3))) & 0xFFFF;
  182. dev_dbg(&bus->dev,
  183. "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
  184. PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
  185. return PCIBIOS_SUCCESSFUL;
  186. }
  187. static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,
  188. int config, int size, u32 value)
  189. {
  190. struct faraday_pci *p = bus->sysdata;
  191. int ret = PCIBIOS_SUCCESSFUL;
  192. dev_dbg(&bus->dev,
  193. "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
  194. PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
  195. writel(PCI_CONF_BUS(bus->number) |
  196. PCI_CONF_DEVICE(PCI_SLOT(fn)) |
  197. PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
  198. PCI_CONF_WHERE(config) |
  199. PCI_CONF_ENABLE,
  200. p->base + PCI_CONFIG);
  201. switch (size) {
  202. case 4:
  203. writel(value, p->base + PCI_DATA);
  204. break;
  205. case 2:
  206. writew(value, p->base + PCI_DATA + (config & 3));
  207. break;
  208. case 1:
  209. writeb(value, p->base + PCI_DATA + (config & 3));
  210. break;
  211. default:
  212. ret = PCIBIOS_BAD_REGISTER_NUMBER;
  213. }
  214. return ret;
  215. }
  216. static struct pci_ops faraday_pci_ops = {
  217. .read = faraday_pci_read_config,
  218. .write = faraday_pci_write_config,
  219. };
  220. static void faraday_pci_ack_irq(struct irq_data *d)
  221. {
  222. struct faraday_pci *p = irq_data_get_irq_chip_data(d);
  223. unsigned int reg;
  224. faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
  225. reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
  226. reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
  227. faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, reg);
  228. }
  229. static void faraday_pci_mask_irq(struct irq_data *d)
  230. {
  231. struct faraday_pci *p = irq_data_get_irq_chip_data(d);
  232. unsigned int reg;
  233. faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
  234. reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
  235. | BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
  236. faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, reg);
  237. }
  238. static void faraday_pci_unmask_irq(struct irq_data *d)
  239. {
  240. struct faraday_pci *p = irq_data_get_irq_chip_data(d);
  241. unsigned int reg;
  242. faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
  243. reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
  244. reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
  245. faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, reg);
  246. }
  247. static void faraday_pci_irq_handler(struct irq_desc *desc)
  248. {
  249. struct faraday_pci *p = irq_desc_get_handler_data(desc);
  250. struct irq_chip *irqchip = irq_desc_get_chip(desc);
  251. unsigned int irq_stat, reg, i;
  252. faraday_pci_read_config(p->bus, 0, FARADAY_PCI_CTRL2, 4, &reg);
  253. irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
  254. chained_irq_enter(irqchip, desc);
  255. for (i = 0; i < 4; i++) {
  256. if ((irq_stat & BIT(i)) == 0)
  257. continue;
  258. generic_handle_irq(irq_find_mapping(p->irqdomain, i));
  259. }
  260. chained_irq_exit(irqchip, desc);
  261. }
  262. static struct irq_chip faraday_pci_irq_chip = {
  263. .name = "PCI",
  264. .irq_ack = faraday_pci_ack_irq,
  265. .irq_mask = faraday_pci_mask_irq,
  266. .irq_unmask = faraday_pci_unmask_irq,
  267. };
  268. static int faraday_pci_irq_map(struct irq_domain *domain, unsigned int irq,
  269. irq_hw_number_t hwirq)
  270. {
  271. irq_set_chip_and_handler(irq, &faraday_pci_irq_chip, handle_level_irq);
  272. irq_set_chip_data(irq, domain->host_data);
  273. return 0;
  274. }
  275. static const struct irq_domain_ops faraday_pci_irqdomain_ops = {
  276. .map = faraday_pci_irq_map,
  277. };
  278. static int faraday_pci_setup_cascaded_irq(struct faraday_pci *p)
  279. {
  280. struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
  281. int irq;
  282. int i;
  283. if (!intc) {
  284. dev_err(p->dev, "missing child interrupt-controller node\n");
  285. return -EINVAL;
  286. }
  287. /* All PCI IRQs cascade off this one */
  288. irq = of_irq_get(intc, 0);
  289. if (!irq) {
  290. dev_err(p->dev, "failed to get parent IRQ\n");
  291. return -EINVAL;
  292. }
  293. p->irqdomain = irq_domain_add_linear(intc, 4,
  294. &faraday_pci_irqdomain_ops, p);
  295. if (!p->irqdomain) {
  296. dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
  297. return -EINVAL;
  298. }
  299. irq_set_chained_handler_and_data(irq, faraday_pci_irq_handler, p);
  300. for (i = 0; i < 4; i++)
  301. irq_create_mapping(p->irqdomain, i);
  302. return 0;
  303. }
  304. static int pci_dma_range_parser_init(struct of_pci_range_parser *parser,
  305. struct device_node *node)
  306. {
  307. const int na = 3, ns = 2;
  308. int rlen;
  309. parser->node = node;
  310. parser->pna = of_n_addr_cells(node);
  311. parser->np = parser->pna + na + ns;
  312. parser->range = of_get_property(node, "dma-ranges", &rlen);
  313. if (!parser->range)
  314. return -ENOENT;
  315. parser->end = parser->range + rlen / sizeof(__be32);
  316. return 0;
  317. }
  318. static int faraday_pci_parse_map_dma_ranges(struct faraday_pci *p,
  319. struct device_node *np)
  320. {
  321. struct of_pci_range range;
  322. struct of_pci_range_parser parser;
  323. struct device *dev = p->dev;
  324. u32 confreg[3] = {
  325. FARADAY_PCI_MEM1_BASE_SIZE,
  326. FARADAY_PCI_MEM2_BASE_SIZE,
  327. FARADAY_PCI_MEM3_BASE_SIZE,
  328. };
  329. int i = 0;
  330. u32 val;
  331. if (pci_dma_range_parser_init(&parser, np)) {
  332. dev_err(dev, "missing dma-ranges property\n");
  333. return -EINVAL;
  334. }
  335. /*
  336. * Get the dma-ranges from the device tree
  337. */
  338. for_each_of_pci_range(&parser, &range) {
  339. u64 end = range.pci_addr + range.size - 1;
  340. int ret;
  341. ret = faraday_res_to_memcfg(range.pci_addr, range.size, &val);
  342. if (ret) {
  343. dev_err(dev,
  344. "DMA range %d: illegal MEM resource size\n", i);
  345. return -EINVAL;
  346. }
  347. dev_info(dev, "DMA MEM%d BASE: 0x%016llx -> 0x%016llx config %08x\n",
  348. i + 1, range.pci_addr, end, val);
  349. if (i <= 2) {
  350. faraday_pci_write_config(p->bus, 0, confreg[i],
  351. 4, val);
  352. } else {
  353. dev_err(dev, "ignore extraneous dma-range %d\n", i);
  354. break;
  355. }
  356. i++;
  357. }
  358. return 0;
  359. }
  360. static int faraday_pci_probe(struct platform_device *pdev)
  361. {
  362. struct device *dev = &pdev->dev;
  363. const struct faraday_pci_variant *variant =
  364. of_device_get_match_data(dev);
  365. struct resource *regs;
  366. resource_size_t io_base;
  367. struct resource_entry *win;
  368. struct faraday_pci *p;
  369. struct resource *mem;
  370. struct resource *io;
  371. struct pci_host_bridge *host;
  372. int ret;
  373. u32 val;
  374. LIST_HEAD(res);
  375. host = pci_alloc_host_bridge(sizeof(*p));
  376. if (!host)
  377. return -ENOMEM;
  378. host->dev.parent = dev;
  379. host->ops = &faraday_pci_ops;
  380. host->busnr = 0;
  381. host->msi = NULL;
  382. p = pci_host_bridge_priv(host);
  383. host->sysdata = p;
  384. p->dev = dev;
  385. regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  386. p->base = devm_ioremap_resource(dev, regs);
  387. if (IS_ERR(p->base))
  388. return PTR_ERR(p->base);
  389. ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
  390. &res, &io_base);
  391. if (ret)
  392. return ret;
  393. ret = devm_request_pci_bus_resources(dev, &res);
  394. if (ret)
  395. return ret;
  396. /* Get the I/O and memory ranges from DT */
  397. resource_list_for_each_entry(win, &res) {
  398. switch (resource_type(win->res)) {
  399. case IORESOURCE_IO:
  400. io = win->res;
  401. io->name = "Gemini PCI I/O";
  402. if (!faraday_res_to_memcfg(io->start - win->offset,
  403. resource_size(io), &val)) {
  404. /* setup I/O space size */
  405. writel(val, p->base + PCI_IOSIZE);
  406. } else {
  407. dev_err(dev, "illegal IO mem size\n");
  408. return -EINVAL;
  409. }
  410. ret = pci_remap_iospace(io, io_base);
  411. if (ret) {
  412. dev_warn(dev, "error %d: failed to map resource %pR\n",
  413. ret, io);
  414. continue;
  415. }
  416. break;
  417. case IORESOURCE_MEM:
  418. mem = win->res;
  419. mem->name = "Gemini PCI MEM";
  420. break;
  421. case IORESOURCE_BUS:
  422. break;
  423. default:
  424. break;
  425. }
  426. }
  427. /* Setup hostbridge */
  428. val = readl(p->base + PCI_CTRL);
  429. val |= PCI_COMMAND_IO;
  430. val |= PCI_COMMAND_MEMORY;
  431. val |= PCI_COMMAND_MASTER;
  432. writel(val, p->base + PCI_CTRL);
  433. list_splice_init(&res, &host->windows);
  434. ret = pci_register_host_bridge(host);
  435. if (ret) {
  436. dev_err(dev, "failed to register host: %d\n", ret);
  437. return ret;
  438. }
  439. p->bus = host->bus;
  440. /* Mask and clear all interrupts */
  441. faraday_pci_write_config(p->bus, 0, FARADAY_PCI_CTRL2 + 2, 2, 0xF000);
  442. if (variant->cascaded_irq) {
  443. ret = faraday_pci_setup_cascaded_irq(p);
  444. if (ret) {
  445. dev_err(dev, "failed to setup cascaded IRQ\n");
  446. return ret;
  447. }
  448. }
  449. ret = faraday_pci_parse_map_dma_ranges(p, dev->of_node);
  450. if (ret)
  451. return ret;
  452. pci_scan_child_bus(p->bus);
  453. pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
  454. pci_bus_assign_resources(p->bus);
  455. pci_bus_add_devices(p->bus);
  456. pci_free_resource_list(&res);
  457. return 0;
  458. }
  459. /*
  460. * We encode bridge variants here, we have at least two so it doesn't
  461. * hurt to have infrastructure to encompass future variants as well.
  462. */
  463. const struct faraday_pci_variant faraday_regular = {
  464. .cascaded_irq = true,
  465. };
  466. const struct faraday_pci_variant faraday_dual = {
  467. .cascaded_irq = false,
  468. };
  469. static const struct of_device_id faraday_pci_of_match[] = {
  470. {
  471. .compatible = "faraday,ftpci100",
  472. .data = &faraday_regular,
  473. },
  474. {
  475. .compatible = "faraday,ftpci100-dual",
  476. .data = &faraday_dual,
  477. },
  478. {},
  479. };
  480. static struct platform_driver faraday_pci_driver = {
  481. .driver = {
  482. .name = "ftpci100",
  483. .of_match_table = of_match_ptr(faraday_pci_of_match),
  484. .suppress_bind_attrs = true,
  485. },
  486. .probe = faraday_pci_probe,
  487. };
  488. builtin_platform_driver(faraday_pci_driver);