imx23_platform.c revision 1.1 1 /* $NetBSD: imx23_platform.c,v 1.1 2025/10/09 06:15:16 skrll Exp $ */
2
3 /*-
4 * Copyright (c) 2025 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Yuri Honegger.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Platform code for the NXP i.MX23 SOC.
34 *
35 * This code is partially based on imx23_olinuxino_machdep.c
36 */
37
38 #include <sys/types.h>
39
40 #include <uvm/uvm_extern.h>
41
42 #include <dev/fdt/fdt_platform.h>
43 #include <dev/fdt/fdtvar.h>
44
45 #include <arch/evbarm/fdt/platform.h>
46 #include <arm/cpufunc.h>
47 #include <arm/fdt/arm_fdtvar.h>
48 #include <arm/imx/imx23_clkctrlreg.h>
49 #include <arm/imx/imx23_digctlreg.h>
50 #include <arm/imx/imx23var.h>
51 #include <evbarm/dev/plcomreg.h>
52
53 #include "opt_console.h"
54
55 #define REG_RD(reg) *(volatile uint32_t *)(reg)
56 #define REG_WR(reg, val) \
57 do { \
58 *(volatile uint32_t *)((reg)) = val; \
59 } while (0)
60
61 void imx23_platform_early_putchar(char);
62
63 static const struct pmap_devmap *imx23_platform_devmap(void);
64
65 void
66 imx23_platform_early_putchar(char c)
67 {
68 #ifdef CONSADDR
69 #define CONSADDR_VA ((CONSADDR - APBH_BASE) + KERNEL_IO_VBASE)
70 volatile uint32_t *uartaddr = cpu_earlydevice_va_p()
71 ? (volatile uint32_t *)CONSADDR_VA
72 : (volatile uint32_t *)CONSADDR;
73
74 while ((le32toh(uartaddr[PL01XCOM_FR / 4]) & PL01X_FR_TXFF) != 0)
75 continue;
76
77 uartaddr[PL01XCOM_DR / 4] = htole32(c);
78 dsb(sy);
79
80 while ((le32toh(uartaddr[PL01XCOM_FR / 4]) & PL01X_FR_TXFE) == 0)
81 continue;
82 #endif
83 }
84
85 static const struct pmap_devmap *
86 imx23_platform_devmap(void) {
87 static const struct pmap_devmap devmap[] = {
88 DEVMAP_ENTRY(
89 APBH_BASE, /* Virtual address. */
90 APBH_BASE, /* Physical address. */
91 APBH_SIZE + APBX_SIZE /* APBX located after APBH. */
92 ),
93 DEVMAP_ENTRY_END
94 };
95
96 return devmap;
97 }
98
99 static void
100 imx23_platform_init_attach_args(struct fdt_attach_args *faa)
101 {
102 faa->faa_bst = &imx23_bus_space;
103 faa->faa_dmat = &imx23_bus_dma_tag;
104 }
105
106 static void
107 imx23_platform_device_register(device_t self, void *aux)
108 {
109 }
110
111 static void
112 imx23_platform_reset(void)
113 {
114 // reboot
115 REG_WR(HW_CLKCTRL_BASE + HW_CLKCTRL_RESET, HW_CLKCTRL_RESET_CHIP);
116 }
117
118 /*
119 * Delay us microseconds.
120 */
121 static void
122 imx23_platform_delay(unsigned int us)
123 {
124 uint32_t start;
125 uint32_t now;
126 uint32_t elapsed;
127 uint32_t total;
128 uint32_t last;
129
130 total = 0;
131 last = 0;
132 start = REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_MICROSECONDS);
133
134 do {
135 now = REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_MICROSECONDS);
136
137 if (start <= now)
138 elapsed = now - start;
139 else /* Take care of overflow. */
140 elapsed = (UINT32_MAX - start) + 1 + now;
141
142 total += elapsed - last;
143 last = elapsed;
144
145 } while (total < us);
146
147 return;
148 }
149
150 static u_int
151 imx23_platform_uart_freq(void)
152 {
153 /* The documentation mentions the uart is driven by a 24MHz clock. */
154 return 24000000;
155 }
156
157 static const struct fdt_platform imx23_platform = {
158 .fp_devmap = imx23_platform_devmap,
159 .fp_bootstrap = arm_fdt_cpu_bootstrap,
160 .fp_init_attach_args = imx23_platform_init_attach_args,
161 .fp_device_register = imx23_platform_device_register,
162 .fp_reset = imx23_platform_reset,
163 .fp_delay = imx23_platform_delay,
164 .fp_uart_freq = imx23_platform_uart_freq,
165 };
166
167 FDT_PLATFORM(imx23, "fsl,imx23", &imx23_platform);
168