1 /* $NetBSD: am3_platform.c,v 1.4 2023/04/07 08:55:30 skrll Exp $ */
2
3 #include "opt_console.h"
4
5 #include <sys/cdefs.h>
6 __KERNEL_RCSID(0, "$NetBSD: am3_platform.c,v 1.4 2023/04/07 08:55:30 skrll Exp $");
7
8 #include <sys/param.h>
9
10 #include <dev/fdt/fdtvar.h>
11
12 #include <arm/fdt/arm_fdtvar.h>
13
14 #include <uvm/uvm_extern.h>
15
16 #include <dev/ic/comreg.h>
17
18 #include <machine/vmparam.h>
19 #include <arch/evbarm/fdt/platform.h>
20
21 extern struct bus_space armv7_generic_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
am33xx_platform_early_putchar(char c)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 *
am33xx_platform_devmap(void)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
am33xx_platform_init_attach_args(struct fdt_attach_args * faa)57 am33xx_platform_init_attach_args(struct fdt_attach_args *faa)
58 {
59 faa->faa_bst = &armv7_generic_bs_tag;
60 faa->faa_dmat = &arm_generic_dma_tag;
61 }
62
63 static void
wdelay(bus_space_tag_t bst,bus_space_handle_t bsh)64 wdelay(bus_space_tag_t bst, bus_space_handle_t bsh)
65 {
66 while (bus_space_read_4(bst, bsh, 0x34) != 0)
67 delay(10);
68 }
69
70 static void
am33xx_platform_bootstrap(void)71 am33xx_platform_bootstrap(void)
72 {
73 static bus_space_tag_t bst = &armv7_generic_bs_tag;
74 static bus_space_handle_t bsh;
75
76 bus_space_map(bst, 0x44e00000, 0x1000, 0, &bsh);
77 bus_space_write_4(bst, bsh, 0x508, 0x1); /* CLKSEL_TIMER2_CLK: CLK_M_OSC */
78 bus_space_write_4(bst, bsh, 0x50c, 0x1); /* CLKSEL_TIMER3_CLK: CLK_M_OSC */
79 bus_space_write_4(bst, bsh, 0x80, 0x2); /* CM_PER_TIMER2_CLKCTRL: MODULEMODE: ENABLE */
80 bus_space_write_4(bst, bsh, 0x84, 0x2); /* CM_PER_TIMER3_CLKCTRL: MODULEMODE: ENABLE */
81 bus_space_unmap(bst, bsh, 0x1000);
82
83 bus_space_map(bst, 0x48040000, 0x1000, 0, &bsh); /* TIMER2 for delay() */
84
85 bus_space_write_4(bst, bsh, 0x40, 0); /* Load */
86 bus_space_write_4(bst, bsh, 0x3c, 0); /* Counter */
87 bus_space_write_4(bst, bsh, 0x38, 3); /* Control */
88
89 bus_space_unmap(bst, bsh, 0x1000);
90
91 bus_space_map(bst, 0x44e35000, 0x1000, 0, &bsh);
92 wdelay(bst, bsh);
93 bus_space_write_4(bst, bsh, 0x48, 0xAAAA);
94 wdelay(bst, bsh);
95 bus_space_write_4(bst, bsh, 0x48, 0x5555);
96 wdelay(bst, bsh);
97 bus_space_unmap(bst, bsh, 0x1000);
98
99 bus_space_map(bst, 0x44e00000, 0x1000, 0, &bsh);
100 bus_space_write_4(bst, bsh, 0x4d4, 0); /* suspend watch dog */
101 bus_space_unmap(bst, bsh, 0x1000);
102 }
103
104 static u_int
am33xx_platform_uart_freq(void)105 am33xx_platform_uart_freq(void)
106 {
107 return 48000000;
108 }
109
110 static void
am33xx_platform_delay(u_int n)111 am33xx_platform_delay(u_int n)
112 {
113 static bus_space_tag_t bst = &armv7_generic_bs_tag;
114 static bus_space_handle_t bsh = 0;
115
116 uint32_t cur, prev;
117 long ticks = n * 24;
118
119 if (bsh == 0)
120 bus_space_map(bst, 0x48040000, 0x1000, 0, &bsh); /* TIMER2 */
121
122 prev = bus_space_read_4(bst, bsh, 0x3c);
123 while (ticks > 0) {
124 cur = bus_space_read_4(bst, bsh, 0x3c);
125 if (cur >= prev)
126 ticks -= (cur - prev);
127 else
128 ticks -= (UINT32_MAX - cur + prev);
129 prev = cur;
130 }
131 }
132
133 static void
am33xx_platform_reset(void)134 am33xx_platform_reset(void)
135 {
136 volatile uint32_t *resetaddr = (volatile uint32_t *)(KERNEL_IO_VBASE | 0x04e00f00);
137
138 *resetaddr = 1;
139 }
140
141 static const struct fdt_platform am33xx_platform = {
142 .fp_devmap = am33xx_platform_devmap,
143 .fp_init_attach_args = am33xx_platform_init_attach_args,
144 .fp_bootstrap = am33xx_platform_bootstrap,
145 .fp_uart_freq = am33xx_platform_uart_freq,
146 .fp_delay = am33xx_platform_delay,
147 .fp_reset = am33xx_platform_reset,
148 };
149
150 FDT_PLATFORM(am33xx, "ti,am33xx", &am33xx_platform);
151