cycv_platform.c revision 1.3 1 /* $NetBSD: cycv_platform.c,v 1.3 2018/10/18 09:01:52 skrll Exp $ */
2
3 /* This file is in the public domain. */
4
5 #include "arml2cc.h"
6 #include "opt_multiprocessor.h"
7
8 #include <sys/cdefs.h>
9 __KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.3 2018/10/18 09:01:52 skrll Exp $");
10
11 #define _ARM32_BUS_DMA_PRIVATE
12 #include <sys/param.h>
13 #include <sys/bus.h>
14 #include <sys/cpu.h>
15 #include <sys/device.h>
16
17 #include <uvm/uvm_extern.h>
18
19 #include <arm/arm32/machdep.h>
20
21 #include <arm/altera/cycv_reg.h>
22 #include <arm/altera/cycv_var.h>
23 #include <arm/cortex/a9tmr_var.h>
24 #include <arm/cortex/pl310_var.h>
25 #include <arm/cortex/scu_reg.h>
26
27 #include <arm/bootconfig.h>
28 #include <arm/cpufunc.h>
29
30 #include <arm/fdt/arm_fdtvar.h>
31 #include <dev/fdt/fdtvar.h>
32
33 static void cycv_platform_early_putchar(char);
34
35 static const struct pmap_devmap *
36 cycv_platform_devmap(void) {
37 static const struct pmap_devmap devmap[] = {
38 DEVMAP_ENTRY(CYCV_PERIPHERAL_VBASE,
39 CYCV_PERIPHERAL_BASE,
40 CYCV_PERIPHERAL_SIZE),
41 DEVMAP_ENTRY_END
42 };
43
44 return devmap;
45 }
46
47 static void
48 cycv_platform_bootstrap(void)
49 {
50 bus_space_tag_t bst = &armv7_generic_bs_tag;
51 bus_space_handle_t bsh_l2c;
52
53 bus_space_map(bst, CYCV_L2CACHE_BASE, CYCV_L2CACHE_SIZE, 0, &bsh_l2c);
54
55 #if NARML2CC > 0
56 arml2cc_init(bst, bsh_l2c, 0);
57 #endif
58 }
59
60 static void
61 cycv_mpstart(void)
62 {
63 bus_space_tag_t bst = &armv7_generic_bs_tag;
64 bus_space_handle_t bsh_rst;
65 bus_space_handle_t bsh_scu;
66
67 bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh_rst);
68 bus_space_map(bst, CYCV_SCU_BASE, CYCV_SCU_SIZE, 0, &bsh_scu);
69
70 /* Enable Snoop Control Unit */
71 bus_space_write_4(bst, bsh_rst, SCU_CTL,
72 bus_space_read_4(bst, bsh_rst, SCU_CTL) | SCU_CTL_SCU_ENA);
73
74 const uint32_t startfunc = (uint32_t) KERN_VTOPHYS((vaddr_t)cpu_mpstart);
75
76 /*
77 * We place a "B cortex_mpstart" at address 0 in order to bootstrap
78 * CPU 1. We can't use the similar feature of the Boot ROM because
79 * it was unmapped by u-boot in favor of the SDRAM. Plus the dtb is
80 * stored very low in RAM so we can't re-map the Boot ROM easily.
81 */
82 extern vaddr_t cpu_ttb;
83
84 pmap_map_chunk(cpu_ttb, CYCV_SDRAM_VBASE, CYCV_SDRAM_BASE, L1_S_SIZE,
85 VM_PROT_READ|VM_PROT_WRITE, PMAP_NOCACHE);
86 *(volatile uint32_t *) CYCV_SDRAM_VBASE =
87 htole32(0xea000000 | ((startfunc - 8 - 0x0) >> 2));
88 pmap_unmap_chunk(cpu_ttb, CYCV_SDRAM_BASE, L1_S_SIZE);
89
90 arm_cpu_max = 2;
91
92 bus_space_write_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST,
93 bus_space_read_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST) &
94 ~CYCV_RSTMGR_MPUMODRST_CPU1);
95 }
96
97 static void
98 cycv_platform_init_attach_args(struct fdt_attach_args *faa) {
99 faa->faa_bst = &armv7_generic_bs_tag;
100 faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
101 faa->faa_dmat = &arm_generic_dma_tag;
102 }
103
104 static void
105 cycv_platform_early_putchar(char c) {
106 #ifdef CONSADDR
107 #define CONSADDR_VA (CONSADDR - CYCV_PERIPHERAL_BASE + CYCV_PERIPHERAL_VBASE)
108 volatile uint32_t *uartaddr = (volatile uint32_t *) CONSADDR_VA;
109
110 while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
111 ;
112
113 uartaddr[com_data] = htole32(c);
114 #endif
115 }
116
117 static void
118 cycv_platform_device_register(device_t dev, void *aux) {
119 prop_dictionary_t dict = device_properties(dev);
120
121 if (device_is_a(dev, "arma9tmr")) {
122 prop_dictionary_set_uint32(dict, "frequency",
123 cycv_clkmgr_early_get_mpu_clk() / 4);
124 }
125 }
126
127 static void
128 cycv_platform_reset(void) {
129 bus_space_tag_t bst = &armv7_generic_bs_tag;
130 bus_space_handle_t bsh;
131 uint32_t val;
132
133 bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh);
134 val = bus_space_read_4(bst, bsh, CYCV_RSTMGR_CTRL);
135 bus_space_write_4(bst, bsh, CYCV_RSTMGR_CTRL,
136 val | CYCV_RSTMGR_CTRL_SWCOLDRSTREQ);
137 }
138
139 static u_int
140 cycv_platform_uart_freq(void) {
141 return cycv_clkmgr_early_get_l4_sp_clk();
142 }
143
144 static const struct arm_platform cycv_platform = {
145 .ap_devmap = cycv_platform_devmap,
146 .ap_bootstrap = cycv_platform_bootstrap,
147 .ap_init_attach_args = cycv_platform_init_attach_args,
148 .ap_early_putchar = cycv_platform_early_putchar,
149 .ap_device_register = cycv_platform_device_register,
150 .ap_reset = cycv_platform_reset,
151 .ap_delay = a9tmr_delay,
152 .ap_uart_freq = cycv_platform_uart_freq,
153 .ap_mpstart = cycv_mpstart,
154 };
155
156 ARM_PLATFORM(cycv, "altr,socfpga-cyclone5", &cycv_platform);
157