axs10x.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * AXS101/AXS103 Software Development Platform
  4. *
  5. * Copyright (C) 2013-15 Synopsys, Inc. (www.synopsys.com)
  6. */
  7. #include <linux/of_fdt.h>
  8. #include <linux/of_platform.h>
  9. #include <linux/libfdt.h>
  10. #include <asm/asm-offsets.h>
  11. #include <asm/io.h>
  12. #include <asm/mach_desc.h>
  13. #include <soc/arc/mcip.h>
  14. #define AXS_MB_CGU 0xE0010000
  15. #define AXS_MB_CREG 0xE0011000
  16. #define CREG_MB_IRQ_MUX (AXS_MB_CREG + 0x214)
  17. #define CREG_MB_SW_RESET (AXS_MB_CREG + 0x220)
  18. #define CREG_MB_VER (AXS_MB_CREG + 0x230)
  19. #define CREG_MB_CONFIG (AXS_MB_CREG + 0x234)
  20. #define AXC001_CREG 0xF0001000
  21. #define AXC001_GPIO_INTC 0xF0003000
  22. static void __init axs10x_enable_gpio_intc_wire(void)
  23. {
  24. /*
  25. * Peripherals on CPU Card and Mother Board are wired to cpu intc via
  26. * intermediate DW APB GPIO blocks (mainly for debouncing)
  27. *
  28. * ---------------------
  29. * | snps,arc700-intc |
  30. * ---------------------
  31. * | #7 | #15
  32. * ------------------- -------------------
  33. * | snps,dw-apb-gpio | | snps,dw-apb-gpio |
  34. * ------------------- -------------------
  35. * | #12 |
  36. * | [ Debug UART on cpu card ]
  37. * |
  38. * ------------------------
  39. * | snps,dw-apb-intc (MB)|
  40. * ------------------------
  41. * | | | |
  42. * [eth] [uart] [... other perip on Main Board]
  43. *
  44. * Current implementation of "irq-dw-apb-ictl" driver doesn't work well
  45. * with stacked INTCs. In particular problem happens if its master INTC
  46. * not yet instantiated. See discussion here -
  47. * https://lore.kernel.org/lkml/[email protected]
  48. *
  49. * So setup the first gpio block as a passive pass thru and hide it from
  50. * DT hardware topology - connect MB intc directly to cpu intc
  51. * The GPIO "wire" needs to be init nevertheless (here)
  52. *
  53. * One side adv is that peripheral interrupt handling avoids one nested
  54. * intc ISR hop
  55. */
  56. #define GPIO_INTEN (AXC001_GPIO_INTC + 0x30)
  57. #define GPIO_INTMASK (AXC001_GPIO_INTC + 0x34)
  58. #define GPIO_INTTYPE_LEVEL (AXC001_GPIO_INTC + 0x38)
  59. #define GPIO_INT_POLARITY (AXC001_GPIO_INTC + 0x3c)
  60. #define MB_TO_GPIO_IRQ 12
  61. iowrite32(~(1 << MB_TO_GPIO_IRQ), (void __iomem *) GPIO_INTMASK);
  62. iowrite32(0, (void __iomem *) GPIO_INTTYPE_LEVEL);
  63. iowrite32(~0, (void __iomem *) GPIO_INT_POLARITY);
  64. iowrite32(1 << MB_TO_GPIO_IRQ, (void __iomem *) GPIO_INTEN);
  65. }
  66. static void __init axs10x_print_board_ver(unsigned int creg, const char *str)
  67. {
  68. union ver {
  69. struct {
  70. #ifdef CONFIG_CPU_BIG_ENDIAN
  71. unsigned int pad:11, y:12, m:4, d:5;
  72. #else
  73. unsigned int d:5, m:4, y:12, pad:11;
  74. #endif
  75. };
  76. unsigned int val;
  77. } board;
  78. board.val = ioread32((void __iomem *)creg);
  79. pr_info("AXS: %s FPGA Date: %u-%u-%u\n", str, board.d, board.m,
  80. board.y);
  81. }
  82. static void __init axs10x_early_init(void)
  83. {
  84. int mb_rev;
  85. char mb[32];
  86. /* Determine motherboard version */
  87. if (ioread32((void __iomem *) CREG_MB_CONFIG) & (1 << 28))
  88. mb_rev = 3; /* HT-3 (rev3.0) */
  89. else
  90. mb_rev = 2; /* HT-2 (rev2.0) */
  91. axs10x_enable_gpio_intc_wire();
  92. scnprintf(mb, 32, "MainBoard v%d", mb_rev);
  93. axs10x_print_board_ver(CREG_MB_VER, mb);
  94. }
  95. #ifdef CONFIG_AXS101
  96. #define CREG_CPU_ADDR_770 (AXC001_CREG + 0x20)
  97. #define CREG_CPU_ADDR_TUNN (AXC001_CREG + 0x60)
  98. #define CREG_CPU_ADDR_770_UPD (AXC001_CREG + 0x34)
  99. #define CREG_CPU_ADDR_TUNN_UPD (AXC001_CREG + 0x74)
  100. #define CREG_CPU_ARC770_IRQ_MUX (AXC001_CREG + 0x114)
  101. #define CREG_CPU_GPIO_UART_MUX (AXC001_CREG + 0x120)
  102. /*
  103. * Set up System Memory Map for ARC cpu / peripherals controllers
  104. *
  105. * Each AXI master has a 4GB memory map specified as 16 apertures of 256MB, each
  106. * of which maps to a corresponding 256MB aperture in Target slave memory map.
  107. *
  108. * e.g. ARC cpu AXI Master's aperture 8 (0x8000_0000) is mapped to aperture 0
  109. * (0x0000_0000) of DDR Port 0 (slave #1)
  110. *
  111. * Access from cpu to MB controllers such as GMAC is setup using AXI Tunnel:
  112. * which has master/slaves on both ends.
  113. * e.g. aperture 14 (0xE000_0000) of ARC cpu is mapped to aperture 14
  114. * (0xE000_0000) of CPU Card AXI Tunnel slave (slave #3) which is mapped to
  115. * MB AXI Tunnel Master, which also has a mem map setup
  116. *
  117. * In the reverse direction, MB AXI Masters (e.g. GMAC) mem map is setup
  118. * to map to MB AXI Tunnel slave which connects to CPU Card AXI Tunnel Master
  119. */
  120. struct aperture {
  121. unsigned int slave_sel:4, slave_off:4, pad:24;
  122. };
  123. /* CPU Card target slaves */
  124. #define AXC001_SLV_NONE 0
  125. #define AXC001_SLV_DDR_PORT0 1
  126. #define AXC001_SLV_SRAM 2
  127. #define AXC001_SLV_AXI_TUNNEL 3
  128. #define AXC001_SLV_AXI2APB 6
  129. #define AXC001_SLV_DDR_PORT1 7
  130. /* MB AXI Target slaves */
  131. #define AXS_MB_SLV_NONE 0
  132. #define AXS_MB_SLV_AXI_TUNNEL_CPU 1
  133. #define AXS_MB_SLV_AXI_TUNNEL_HAPS 2
  134. #define AXS_MB_SLV_SRAM 3
  135. #define AXS_MB_SLV_CONTROL 4
  136. /* MB AXI masters */
  137. #define AXS_MB_MST_TUNNEL_CPU 0
  138. #define AXS_MB_MST_USB_OHCI 10
  139. /*
  140. * memmap for ARC core on CPU Card
  141. */
  142. static const struct aperture axc001_memmap[16] = {
  143. {AXC001_SLV_AXI_TUNNEL, 0x0},
  144. {AXC001_SLV_AXI_TUNNEL, 0x1},
  145. {AXC001_SLV_SRAM, 0x0}, /* 0x2000_0000: Local SRAM */
  146. {AXC001_SLV_NONE, 0x0},
  147. {AXC001_SLV_NONE, 0x0},
  148. {AXC001_SLV_NONE, 0x0},
  149. {AXC001_SLV_NONE, 0x0},
  150. {AXC001_SLV_NONE, 0x0},
  151. {AXC001_SLV_DDR_PORT0, 0x0}, /* 0x8000_0000: DDR 0..256M */
  152. {AXC001_SLV_DDR_PORT0, 0x1}, /* 0x9000_0000: DDR 256..512M */
  153. {AXC001_SLV_DDR_PORT0, 0x2},
  154. {AXC001_SLV_DDR_PORT0, 0x3},
  155. {AXC001_SLV_NONE, 0x0},
  156. {AXC001_SLV_AXI_TUNNEL, 0xD},
  157. {AXC001_SLV_AXI_TUNNEL, 0xE}, /* MB: CREG, CGU... */
  158. {AXC001_SLV_AXI2APB, 0x0}, /* CPU Card local CREG, CGU... */
  159. };
  160. /*
  161. * memmap for CPU Card AXI Tunnel Master (for access by MB controllers)
  162. * GMAC (MB) -> MB AXI Tunnel slave -> CPU Card AXI Tunnel Master -> DDR
  163. */
  164. static const struct aperture axc001_axi_tunnel_memmap[16] = {
  165. {AXC001_SLV_AXI_TUNNEL, 0x0},
  166. {AXC001_SLV_AXI_TUNNEL, 0x1},
  167. {AXC001_SLV_SRAM, 0x0},
  168. {AXC001_SLV_NONE, 0x0},
  169. {AXC001_SLV_NONE, 0x0},
  170. {AXC001_SLV_NONE, 0x0},
  171. {AXC001_SLV_NONE, 0x0},
  172. {AXC001_SLV_NONE, 0x0},
  173. {AXC001_SLV_DDR_PORT1, 0x0},
  174. {AXC001_SLV_DDR_PORT1, 0x1},
  175. {AXC001_SLV_DDR_PORT1, 0x2},
  176. {AXC001_SLV_DDR_PORT1, 0x3},
  177. {AXC001_SLV_NONE, 0x0},
  178. {AXC001_SLV_AXI_TUNNEL, 0xD},
  179. {AXC001_SLV_AXI_TUNNEL, 0xE},
  180. {AXC001_SLV_AXI2APB, 0x0},
  181. };
  182. /*
  183. * memmap for MB AXI Masters
  184. * Same mem map for all perip controllers as well as MB AXI Tunnel Master
  185. */
  186. static const struct aperture axs_mb_memmap[16] = {
  187. {AXS_MB_SLV_SRAM, 0x0},
  188. {AXS_MB_SLV_SRAM, 0x0},
  189. {AXS_MB_SLV_NONE, 0x0},
  190. {AXS_MB_SLV_NONE, 0x0},
  191. {AXS_MB_SLV_NONE, 0x0},
  192. {AXS_MB_SLV_NONE, 0x0},
  193. {AXS_MB_SLV_NONE, 0x0},
  194. {AXS_MB_SLV_NONE, 0x0},
  195. {AXS_MB_SLV_AXI_TUNNEL_CPU, 0x8}, /* DDR on CPU Card */
  196. {AXS_MB_SLV_AXI_TUNNEL_CPU, 0x9}, /* DDR on CPU Card */
  197. {AXS_MB_SLV_AXI_TUNNEL_CPU, 0xA},
  198. {AXS_MB_SLV_AXI_TUNNEL_CPU, 0xB},
  199. {AXS_MB_SLV_NONE, 0x0},
  200. {AXS_MB_SLV_AXI_TUNNEL_HAPS, 0xD},
  201. {AXS_MB_SLV_CONTROL, 0x0}, /* MB Local CREG, CGU... */
  202. {AXS_MB_SLV_AXI_TUNNEL_CPU, 0xF},
  203. };
  204. static noinline void __init
  205. axs101_set_memmap(void __iomem *base, const struct aperture map[16])
  206. {
  207. unsigned int slave_select, slave_offset;
  208. int i;
  209. slave_select = slave_offset = 0;
  210. for (i = 0; i < 8; i++) {
  211. slave_select |= map[i].slave_sel << (i << 2);
  212. slave_offset |= map[i].slave_off << (i << 2);
  213. }
  214. iowrite32(slave_select, base + 0x0); /* SLV0 */
  215. iowrite32(slave_offset, base + 0x8); /* OFFSET0 */
  216. slave_select = slave_offset = 0;
  217. for (i = 0; i < 8; i++) {
  218. slave_select |= map[i+8].slave_sel << (i << 2);
  219. slave_offset |= map[i+8].slave_off << (i << 2);
  220. }
  221. iowrite32(slave_select, base + 0x4); /* SLV1 */
  222. iowrite32(slave_offset, base + 0xC); /* OFFSET1 */
  223. }
  224. static void __init axs101_early_init(void)
  225. {
  226. int i;
  227. /* ARC 770D memory view */
  228. axs101_set_memmap((void __iomem *) CREG_CPU_ADDR_770, axc001_memmap);
  229. iowrite32(1, (void __iomem *) CREG_CPU_ADDR_770_UPD);
  230. /* AXI tunnel memory map (incoming traffic from MB into CPU Card */
  231. axs101_set_memmap((void __iomem *) CREG_CPU_ADDR_TUNN,
  232. axc001_axi_tunnel_memmap);
  233. iowrite32(1, (void __iomem *) CREG_CPU_ADDR_TUNN_UPD);
  234. /* MB peripherals memory map */
  235. for (i = AXS_MB_MST_TUNNEL_CPU; i <= AXS_MB_MST_USB_OHCI; i++)
  236. axs101_set_memmap((void __iomem *) AXS_MB_CREG + (i << 4),
  237. axs_mb_memmap);
  238. iowrite32(0x3ff, (void __iomem *) AXS_MB_CREG + 0x100); /* Update */
  239. /* GPIO pins 18 and 19 are used as UART rx and tx, respectively. */
  240. iowrite32(0x01, (void __iomem *) CREG_CPU_GPIO_UART_MUX);
  241. /* Set up the MB interrupt system: mux interrupts to GPIO7) */
  242. iowrite32(0x01, (void __iomem *) CREG_MB_IRQ_MUX);
  243. /* reset ethernet and ULPI interfaces */
  244. iowrite32(0x18, (void __iomem *) CREG_MB_SW_RESET);
  245. /* map GPIO 14:10 to ARC 9:5 (IRQ mux change for MB v2 onwards) */
  246. iowrite32(0x52, (void __iomem *) CREG_CPU_ARC770_IRQ_MUX);
  247. axs10x_early_init();
  248. }
  249. #endif /* CONFIG_AXS101 */
  250. #ifdef CONFIG_AXS103
  251. #define AXC003_CREG 0xF0001000
  252. #define AXC003_MST_AXI_TUNNEL 0
  253. #define AXC003_MST_HS38 1
  254. #define CREG_CPU_AXI_M0_IRQ_MUX (AXC003_CREG + 0x440)
  255. #define CREG_CPU_GPIO_UART_MUX (AXC003_CREG + 0x480)
  256. #define CREG_CPU_TUN_IO_CTRL (AXC003_CREG + 0x494)
  257. static void __init axs103_early_init(void)
  258. {
  259. #ifdef CONFIG_ARC_MCIP
  260. /*
  261. * AXS103 configurations for SMP/QUAD configurations share device tree
  262. * which defaults to 100 MHz. However recent failures of Quad config
  263. * revealed P&R timing violations so clamp it down to safe 50 MHz
  264. * Instead of duplicating defconfig/DT for SMP/QUAD, add a small hack
  265. * of fudging the freq in DT
  266. */
  267. #define AXS103_QUAD_CORE_CPU_FREQ_HZ 50000000
  268. unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F;
  269. if (num_cores > 2) {
  270. u32 freq;
  271. int off = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk");
  272. const struct fdt_property *prop;
  273. prop = fdt_get_property(initial_boot_params, off,
  274. "assigned-clock-rates", NULL);
  275. freq = be32_to_cpu(*(u32 *)(prop->data));
  276. /* Patching .dtb in-place with new core clock value */
  277. if (freq != AXS103_QUAD_CORE_CPU_FREQ_HZ) {
  278. freq = cpu_to_be32(AXS103_QUAD_CORE_CPU_FREQ_HZ);
  279. fdt_setprop_inplace(initial_boot_params, off,
  280. "assigned-clock-rates", &freq, sizeof(freq));
  281. }
  282. }
  283. #endif
  284. /* Memory maps already config in pre-bootloader */
  285. /* set GPIO mux to UART */
  286. iowrite32(0x01, (void __iomem *) CREG_CPU_GPIO_UART_MUX);
  287. iowrite32((0x00100000U | 0x000C0000U | 0x00003322U),
  288. (void __iomem *) CREG_CPU_TUN_IO_CTRL);
  289. /* Set up the AXS_MB interrupt system.*/
  290. iowrite32(12, (void __iomem *) (CREG_CPU_AXI_M0_IRQ_MUX
  291. + (AXC003_MST_HS38 << 2)));
  292. /* connect ICTL - Main Board with GPIO line */
  293. iowrite32(0x01, (void __iomem *) CREG_MB_IRQ_MUX);
  294. axs10x_print_board_ver(AXC003_CREG + 4088, "AXC003 CPU Card");
  295. axs10x_early_init();
  296. }
  297. #endif
  298. #ifdef CONFIG_AXS101
  299. static const char *axs101_compat[] __initconst = {
  300. "snps,axs101",
  301. NULL,
  302. };
  303. MACHINE_START(AXS101, "axs101")
  304. .dt_compat = axs101_compat,
  305. .init_early = axs101_early_init,
  306. MACHINE_END
  307. #endif /* CONFIG_AXS101 */
  308. #ifdef CONFIG_AXS103
  309. static const char *axs103_compat[] __initconst = {
  310. "snps,axs103",
  311. NULL,
  312. };
  313. MACHINE_START(AXS103, "axs103")
  314. .dt_compat = axs103_compat,
  315. .init_early = axs103_early_init,
  316. MACHINE_END
  317. /*
  318. * For the VDK OS-kit, to get the offset to pid and command fields
  319. */
  320. char coware_swa_pid_offset[TASK_PID];
  321. char coware_swa_comm_offset[TASK_COMM];
  322. #endif /* CONFIG_AXS103 */