axs10x.c 11 KB

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