1 /* $NetBSD: omap3_platform.c,v 1.8 2023/04/07 08:55:30 skrll Exp $ */
2
3 /*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include "opt_soc.h"
30 #include "opt_console.h"
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: omap3_platform.c,v 1.8 2023/04/07 08:55:30 skrll Exp $");
34
35 #include <sys/param.h>
36 #include <sys/bus.h>
37 #include <sys/cpu.h>
38 #include <sys/device.h>
39 #include <sys/termios.h>
40
41 #include <dev/fdt/fdtvar.h>
42
43 #include <arm/fdt/arm_fdtvar.h>
44
45 #include <uvm/uvm_extern.h>
46
47 #include <machine/bootconfig.h>
48 #include <arm/cpufunc.h>
49
50 #include <dev/ic/ns16550reg.h>
51 #include <dev/ic/comreg.h>
52
53 #include <evbarm/fdt/platform.h>
54 #include <evbarm/fdt/machdep.h>
55
56 #include <net/if_ether.h>
57
58 #include <libfdt.h>
59
60 #define OMAP3_L4_CORE_VBASE KERNEL_IO_VBASE
61 #define OMAP3_L4_CORE_PBASE 0x48000000
62 #define OMAP3_L4_CORE_SIZE 0x00100000
63
64 #define OMAP3_L4_WKUP_VBASE (OMAP3_L4_CORE_VBASE + OMAP3_L4_CORE_SIZE)
65 #define OMAP3_L4_WKUP_PBASE 0x48300000
66 #define OMAP3_L4_WKUP_SIZE 0x00100000
67
68 #define OMAP3_L4_PER_VBASE (OMAP3_L4_WKUP_VBASE + OMAP3_L4_WKUP_SIZE)
69 #define OMAP3_L4_PER_PBASE 0x49000000
70 #define OMAP3_L4_PER_SIZE 0x00100000
71
72 #define OMAP3_PRCM_BASE 0x48306000
73 #define OMAP3_PRCM_GR_BASE (OMAP3_PRCM_BASE + 0x1200)
74 #define PRM_RSTCTRL (OMAP3_PRCM_GR_BASE + 0x50)
75 #define PRM_RSTCTRL_RST_DPLL3 __BIT(2)
76
77 #define OMAP3_32KTIMER_BASE 0x48320000
78 #define REG_32KSYNCNT_CR (OMAP3_32KTIMER_BASE + 0x10)
79
80 static inline vaddr_t
omap3_phystovirt(paddr_t pa)81 omap3_phystovirt(paddr_t pa)
82 {
83 if (pa >= OMAP3_L4_CORE_PBASE &&
84 pa < OMAP3_L4_CORE_PBASE + OMAP3_L4_CORE_SIZE)
85 return (pa - OMAP3_L4_CORE_PBASE) + OMAP3_L4_CORE_VBASE;
86
87 if (pa >= OMAP3_L4_WKUP_PBASE &&
88 pa < OMAP3_L4_WKUP_PBASE + OMAP3_L4_WKUP_SIZE)
89 return (pa - OMAP3_L4_WKUP_PBASE) + OMAP3_L4_WKUP_VBASE;
90
91 if (pa >= OMAP3_L4_PER_PBASE &&
92 pa < OMAP3_L4_PER_PBASE + OMAP3_L4_PER_SIZE)
93 return (pa - OMAP3_L4_PER_PBASE) + OMAP3_L4_PER_VBASE;
94
95 panic("%s: pa %#x not in devmap", __func__, (uint32_t)pa);
96 }
97
98 #define OMAP3_PHYSTOVIRT(pa) \
99 (((pa) - OMAP3_L4_CORE_VBASE) + OMAP3_L4_CORE_PBASE)
100
101 extern struct arm32_bus_dma_tag arm_generic_dma_tag;
102 extern struct bus_space arm_generic_bs_tag;
103
104 static const struct pmap_devmap *
omap3_platform_devmap(void)105 omap3_platform_devmap(void)
106 {
107 static const struct pmap_devmap devmap[] = {
108 DEVMAP_ENTRY(OMAP3_L4_CORE_VBASE,
109 OMAP3_L4_CORE_PBASE,
110 OMAP3_L4_CORE_SIZE),
111 DEVMAP_ENTRY(OMAP3_L4_WKUP_VBASE,
112 OMAP3_L4_WKUP_PBASE,
113 OMAP3_L4_WKUP_SIZE),
114 DEVMAP_ENTRY(OMAP3_L4_PER_VBASE,
115 OMAP3_L4_PER_PBASE,
116 OMAP3_L4_PER_SIZE),
117 DEVMAP_ENTRY_END
118 };
119
120 return devmap;
121 }
122
123 static void
omap3_platform_init_attach_args(struct fdt_attach_args * faa)124 omap3_platform_init_attach_args(struct fdt_attach_args *faa)
125 {
126 faa->faa_bst = &arm_generic_bs_tag;
127 faa->faa_dmat = &arm_generic_dma_tag;
128 }
129
130 void omap3_platform_early_putchar(char);
131
132 void __noasan
omap3_platform_early_putchar(char c)133 omap3_platform_early_putchar(char c)
134 {
135 #ifdef CONSADDR
136 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
137 (volatile uint32_t *)omap3_phystovirt(CONSADDR):
138 (volatile uint32_t *)CONSADDR;
139
140 while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
141 ;
142
143 uartaddr[com_data] = htole32(c);
144 #endif
145 }
146
147 static void
omap3_platform_device_register(device_t self,void * aux)148 omap3_platform_device_register(device_t self, void *aux)
149 {
150 }
151
152 static u_int
omap3_platform_uart_freq(void)153 omap3_platform_uart_freq(void)
154 {
155 return 48000000U;
156 }
157
158 static void
omap3_platform_reset(void)159 omap3_platform_reset(void)
160 {
161 volatile uint32_t *rstctrl =
162 (volatile uint32_t *)omap3_phystovirt(PRM_RSTCTRL);
163
164 *rstctrl |= PRM_RSTCTRL_RST_DPLL3;
165
166 for (;;)
167 __asm("wfi");
168 }
169
170 static void
omap3_platform_delay(u_int n)171 omap3_platform_delay(u_int n)
172 {
173 volatile uint32_t *cr =
174 (volatile uint32_t *)omap3_phystovirt(REG_32KSYNCNT_CR);
175 uint32_t cur, prev;
176
177 long ticks = howmany(n * 32768, 1000000);
178 prev = *cr;
179 while (ticks > 0) {
180 cur = *cr;
181 if (cur >= prev)
182 ticks -= (cur - prev);
183 else
184 ticks -= (UINT32_MAX - cur + prev);
185 prev = cur;
186 }
187 }
188
189 static const struct fdt_platform omap3_platform = {
190 .fp_devmap = omap3_platform_devmap,
191 .fp_bootstrap = arm_fdt_cpu_bootstrap,
192 .fp_init_attach_args = omap3_platform_init_attach_args,
193 .fp_device_register = omap3_platform_device_register,
194 .fp_reset = omap3_platform_reset,
195 .fp_delay = omap3_platform_delay,
196 .fp_uart_freq = omap3_platform_uart_freq,
197 };
198
199 FDT_PLATFORM(omap3, "ti,omap3", &omap3_platform);
200