xref: /netbsd-src/sys/arch/arm/ti/am3_platform.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /* $NetBSD: am3_platform.c,v 1.2 2020/07/10 12:25:10 skrll Exp $ */
2 
3 #include "opt_console.h"
4 
5 #include <sys/cdefs.h>
6 __KERNEL_RCSID(0, "$NetBSD: am3_platform.c,v 1.2 2020/07/10 12:25:10 skrll Exp $");
7 
8 #include <sys/param.h>
9 
10 #include <dev/fdt/fdtvar.h>
11 #include <arm/fdt/arm_fdtvar.h>
12 
13 #include <uvm/uvm_extern.h>
14 
15 #include <dev/ic/comreg.h>
16 
17 #include <machine/vmparam.h>
18 #include <arch/evbarm/fdt/platform.h>
19 
20 extern struct bus_space armv7_generic_bs_tag;
21 extern struct bus_space armv7_generic_a4x_bs_tag;
22 extern struct arm32_bus_dma_tag arm_generic_dma_tag;
23 
24 void am33xx_platform_early_putchar(char);
25 
26 void __noasan
27 am33xx_platform_early_putchar(char c)
28 {
29 #ifdef CONSADDR
30 #define CONSADDR_VA ((CONSADDR - 0x44c00000) + (KERNEL_IO_VBASE | 0x04c00000))
31 	volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
32 	    (volatile uint32_t *)CONSADDR_VA :
33 	    (volatile uint32_t *)CONSADDR;
34 
35 	while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
36 		;
37 
38 	uartaddr[com_data] = htole32(c);
39 #endif
40 }
41 
42 
43 static const struct pmap_devmap *
44 am33xx_platform_devmap(void)
45 {
46 	static const struct pmap_devmap devmap[] = {
47 		DEVMAP_ENTRY(KERNEL_IO_VBASE | 0x04c00000, 0x44c00000, 0x00400000),
48 		DEVMAP_ENTRY(KERNEL_IO_VBASE | 0x08000000, 0x48000000, 0x01000000),
49 		DEVMAP_ENTRY(KERNEL_IO_VBASE | 0x0a000000, 0x4a000000, 0x01000000),
50 		DEVMAP_ENTRY_END
51 	};
52 
53 	return devmap;
54 }
55 
56 static void
57 am33xx_platform_init_attach_args(struct fdt_attach_args *faa)
58 {
59 	faa->faa_bst = &armv7_generic_bs_tag;
60 	faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
61 	faa->faa_dmat = &arm_generic_dma_tag;
62 }
63 
64 static void
65 wdelay(bus_space_tag_t bst, bus_space_handle_t bsh)
66 {
67 	while (bus_space_read_4(bst, bsh, 0x34) != 0)
68 		delay(10);
69 }
70 
71 static void
72 am33xx_platform_bootstrap(void)
73 {
74 	static bus_space_tag_t bst = &armv7_generic_bs_tag;
75 	static bus_space_handle_t bsh;
76 
77 	bus_space_map(bst, 0x44e00000, 0x1000, 0, &bsh);
78 	bus_space_write_4(bst, bsh, 0x508, 0x1); /* CLKSEL_TIMER2_CLK: CLK_M_OSC */
79 	bus_space_write_4(bst, bsh, 0x50c, 0x1); /* CLKSEL_TIMER3_CLK: CLK_M_OSC */
80 	bus_space_write_4(bst, bsh, 0x80, 0x2); /* CM_PER_TIMER2_CLKCTRL: MODULEMODE: ENABLE */
81 	bus_space_write_4(bst, bsh, 0x84, 0x2); /* CM_PER_TIMER3_CLKCTRL: MODULEMODE: ENABLE */
82 	bus_space_unmap(bst, bsh, 0x1000);
83 
84 	bus_space_map(bst, 0x48040000, 0x1000, 0, &bsh); /* TIMER2 for delay() */
85 
86 	bus_space_write_4(bst, bsh, 0x40, 0); /* Load */
87 	bus_space_write_4(bst, bsh, 0x3c, 0); /* Counter */
88 	bus_space_write_4(bst, bsh, 0x38, 3); /* Control */
89 
90 	bus_space_unmap(bst, bsh, 0x1000);
91 
92 	bus_space_map(bst, 0x44e35000, 0x1000, 0, &bsh);
93 	wdelay(bst, bsh);
94 	bus_space_write_4(bst, bsh, 0x48, 0xAAAA);
95 	wdelay(bst, bsh);
96 	bus_space_write_4(bst, bsh, 0x48, 0x5555);
97 	wdelay(bst, bsh);
98 	bus_space_unmap(bst, bsh, 0x1000);
99 
100 	bus_space_map(bst, 0x44e00000, 0x1000, 0, &bsh);
101 	bus_space_write_4(bst, bsh, 0x4d4, 0); /* suspend watch dog */
102 	bus_space_unmap(bst, bsh, 0x1000);
103 }
104 
105 static u_int
106 am33xx_platform_uart_freq(void)
107 {
108 	return 48000000;
109 }
110 
111 static void
112 am33xx_platform_delay(u_int n)
113 {
114 	static bus_space_tag_t bst = &armv7_generic_bs_tag;
115 	static bus_space_handle_t bsh = 0;
116 
117 	uint32_t cur, prev;
118 	long ticks = n * 24;
119 
120 	if (bsh == 0)
121 		bus_space_map(bst, 0x48040000, 0x1000, 0, &bsh); /* TIMER2 */
122 
123 	prev = bus_space_read_4(bst, bsh, 0x3c);
124 	while (ticks > 0) {
125 		cur = bus_space_read_4(bst, bsh, 0x3c);
126 		if (cur >= prev)
127 			ticks -= (cur - prev);
128 		else
129 			ticks -= (UINT32_MAX - cur + prev);
130 		prev = cur;
131 	}
132 }
133 
134 static void
135 am33xx_platform_reset(void)
136 {
137 	volatile uint32_t *resetaddr = (volatile uint32_t *)(KERNEL_IO_VBASE | 0x04e00f00);
138 
139 	*resetaddr = 1;
140 }
141 
142 static const struct arm_platform am33xx_platform = {
143 	.ap_devmap = am33xx_platform_devmap,
144 	.ap_init_attach_args = am33xx_platform_init_attach_args,
145 	.ap_bootstrap = am33xx_platform_bootstrap,
146 	.ap_uart_freq = am33xx_platform_uart_freq,
147 	.ap_delay = am33xx_platform_delay,
148 	.ap_reset = am33xx_platform_reset,
149 };
150 
151 ARM_PLATFORM(am33xx, "ti,am33xx", &am33xx_platform);
152