1*8d564c5dSskrll /* $NetBSD: rk_platform.c,v 1.17 2023/04/07 08:55:30 skrll Exp $ */
26726462dSjmcneill
36726462dSjmcneill /*-
401470923Sjmcneill * Copyright (c) 2018,2021 Jared McNeill <jmcneill@invisible.ca>
56726462dSjmcneill * All rights reserved.
66726462dSjmcneill *
76726462dSjmcneill * Redistribution and use in source and binary forms, with or without
86726462dSjmcneill * modification, are permitted provided that the following conditions
96726462dSjmcneill * are met:
106726462dSjmcneill * 1. Redistributions of source code must retain the above copyright
116726462dSjmcneill * notice, this list of conditions and the following disclaimer.
126726462dSjmcneill * 2. Redistributions in binary form must reproduce the above copyright
136726462dSjmcneill * notice, this list of conditions and the following disclaimer in the
146726462dSjmcneill * documentation and/or other materials provided with the distribution.
156726462dSjmcneill *
166726462dSjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
176726462dSjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
186726462dSjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
196726462dSjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
206726462dSjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
216726462dSjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
226726462dSjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
236726462dSjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
246726462dSjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256726462dSjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
266726462dSjmcneill * SUCH DAMAGE.
276726462dSjmcneill */
286726462dSjmcneill
296726462dSjmcneill #include "opt_soc.h"
306726462dSjmcneill #include "opt_multiprocessor.h"
315a821b2cSskrll #include "opt_console.h"
326726462dSjmcneill
336726462dSjmcneill #include <sys/cdefs.h>
34*8d564c5dSskrll __KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.17 2023/04/07 08:55:30 skrll Exp $");
356726462dSjmcneill
366726462dSjmcneill #include <sys/param.h>
376726462dSjmcneill #include <sys/bus.h>
386726462dSjmcneill #include <sys/cpu.h>
396726462dSjmcneill #include <sys/device.h>
406726462dSjmcneill #include <sys/termios.h>
416726462dSjmcneill
426726462dSjmcneill #include <dev/fdt/fdtvar.h>
43*8d564c5dSskrll
446726462dSjmcneill #include <arm/fdt/arm_fdtvar.h>
456726462dSjmcneill
466726462dSjmcneill #include <uvm/uvm_extern.h>
476726462dSjmcneill
486726462dSjmcneill #include <machine/bootconfig.h>
496726462dSjmcneill #include <arm/cpufunc.h>
506726462dSjmcneill
516726462dSjmcneill #include <arm/cortex/gtmr_var.h>
526726462dSjmcneill
536726462dSjmcneill #include <dev/ic/ns16550reg.h>
546726462dSjmcneill #include <dev/ic/comreg.h>
556726462dSjmcneill
566726462dSjmcneill #include <arm/arm/psci.h>
5766d31a2dSryo #include <arm/fdt/psci_fdtvar.h>
586726462dSjmcneill
596726462dSjmcneill #include <libfdt.h>
606726462dSjmcneill
616726462dSjmcneill extern struct arm32_bus_dma_tag arm_generic_dma_tag;
626726462dSjmcneill extern struct bus_space arm_generic_bs_tag;
636726462dSjmcneill
646726462dSjmcneill static void
rk_platform_init_attach_args(struct fdt_attach_args * faa)656726462dSjmcneill rk_platform_init_attach_args(struct fdt_attach_args *faa)
666726462dSjmcneill {
676726462dSjmcneill faa->faa_bst = &arm_generic_bs_tag;
686726462dSjmcneill faa->faa_dmat = &arm_generic_dma_tag;
696726462dSjmcneill }
706726462dSjmcneill
716726462dSjmcneill static void
rk_platform_device_register(device_t self,void * aux)726726462dSjmcneill rk_platform_device_register(device_t self, void *aux)
736726462dSjmcneill {
746726462dSjmcneill }
756726462dSjmcneill
766726462dSjmcneill static void
rk_platform_bootstrap(void)776726462dSjmcneill rk_platform_bootstrap(void)
786726462dSjmcneill {
796726462dSjmcneill void *fdt_data = __UNCONST(fdtbus_get_data());
806726462dSjmcneill
8166d31a2dSryo arm_fdt_cpu_bootstrap();
826726462dSjmcneill
836726462dSjmcneill const int chosen_off = fdt_path_offset(fdt_data, "/chosen");
846726462dSjmcneill if (chosen_off < 0)
856726462dSjmcneill return;
866726462dSjmcneill
876726462dSjmcneill if (match_bootconf_option(boot_args, "console", "fb")) {
886726462dSjmcneill const int framebuffer_off =
896726462dSjmcneill fdt_path_offset(fdt_data, "/chosen/framebuffer");
906726462dSjmcneill if (framebuffer_off >= 0) {
916726462dSjmcneill const char *status = fdt_getprop(fdt_data,
926726462dSjmcneill framebuffer_off, "status", NULL);
936726462dSjmcneill if (status == NULL || strncmp(status, "ok", 2) == 0) {
946726462dSjmcneill fdt_setprop_string(fdt_data, chosen_off,
956726462dSjmcneill "stdout-path", "/chosen/framebuffer");
966726462dSjmcneill }
976726462dSjmcneill }
986726462dSjmcneill } else if (match_bootconf_option(boot_args, "console", "serial")) {
996726462dSjmcneill fdt_setprop_string(fdt_data, chosen_off,
1006726462dSjmcneill "stdout-path", "serial0:115200n8");
1016726462dSjmcneill }
1026726462dSjmcneill }
1036726462dSjmcneill
10401470923Sjmcneill #ifdef SOC_RK3288
10501470923Sjmcneill
10601470923Sjmcneill #define RK3288_WDT_BASE 0xff800000
10701470923Sjmcneill #define RK3288_WDT_SIZE 0x10000
10801470923Sjmcneill
10901470923Sjmcneill #define RK3288_WDT_CR 0x0000
11001470923Sjmcneill #define RK3288_WDT_CR_WDT_EN __BIT(0)
11101470923Sjmcneill #define RK3288_WDT_TORR 0x0004
11201470923Sjmcneill #define RK3288_WDT_CRR 0x000c
11301470923Sjmcneill #define RK3288_WDT_MAGIC 0x76
11401470923Sjmcneill
11501470923Sjmcneill static bus_space_handle_t rk3288_wdt_bsh;
11601470923Sjmcneill
11701470923Sjmcneill #include <arm/rockchip/rk3288_platform.h>
11801470923Sjmcneill
11901470923Sjmcneill static const struct pmap_devmap *
rk3288_platform_devmap(void)12001470923Sjmcneill rk3288_platform_devmap(void)
12101470923Sjmcneill {
12201470923Sjmcneill static const struct pmap_devmap devmap[] = {
12301470923Sjmcneill DEVMAP_ENTRY(RK3288_CORE_VBASE,
12401470923Sjmcneill RK3288_CORE_PBASE,
12501470923Sjmcneill RK3288_CORE_SIZE),
12601470923Sjmcneill DEVMAP_ENTRY_END
12701470923Sjmcneill };
12801470923Sjmcneill
12901470923Sjmcneill return devmap;
13001470923Sjmcneill }
13101470923Sjmcneill
13201470923Sjmcneill void rk3288_platform_early_putchar(char);
13301470923Sjmcneill
13401470923Sjmcneill void __noasan
rk3288_platform_early_putchar(char c)13501470923Sjmcneill rk3288_platform_early_putchar(char c)
13601470923Sjmcneill {
13701470923Sjmcneill #ifdef CONSADDR
13801470923Sjmcneill #define CONSADDR_VA ((CONSADDR - RK3288_CORE_PBASE) + RK3288_CORE_VBASE)
13901470923Sjmcneill volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
14001470923Sjmcneill (volatile uint32_t *)CONSADDR_VA :
14101470923Sjmcneill (volatile uint32_t *)CONSADDR;
14201470923Sjmcneill
14301470923Sjmcneill while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
14401470923Sjmcneill ;
14501470923Sjmcneill
14601470923Sjmcneill uartaddr[com_data] = htole32(c);
14701470923Sjmcneill #undef CONSADDR_VA
14801470923Sjmcneill #endif
14901470923Sjmcneill }
15001470923Sjmcneill
15101470923Sjmcneill static void
rk3288_platform_bootstrap(void)15201470923Sjmcneill rk3288_platform_bootstrap(void)
15301470923Sjmcneill {
15401470923Sjmcneill bus_space_tag_t bst = &arm_generic_bs_tag;
15501470923Sjmcneill
15601470923Sjmcneill rk_platform_bootstrap();
15701470923Sjmcneill bus_space_map(bst, RK3288_WDT_BASE, RK3288_WDT_SIZE, 0, &rk3288_wdt_bsh);
15801470923Sjmcneill }
15901470923Sjmcneill
16001470923Sjmcneill static void
rk3288_platform_reset(void)16101470923Sjmcneill rk3288_platform_reset(void)
16201470923Sjmcneill {
16301470923Sjmcneill bus_space_tag_t bst = &arm_generic_bs_tag;
16401470923Sjmcneill
16501470923Sjmcneill bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_TORR, 0);
16601470923Sjmcneill bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_CRR, RK3288_WDT_MAGIC);
16701470923Sjmcneill for (;;) {
16801470923Sjmcneill bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_CR, RK3288_WDT_CR_WDT_EN);
16901470923Sjmcneill }
17001470923Sjmcneill }
17101470923Sjmcneill
17201470923Sjmcneill static u_int
rk3288_platform_uart_freq(void)17301470923Sjmcneill rk3288_platform_uart_freq(void)
17401470923Sjmcneill {
17501470923Sjmcneill return RK3288_UART_FREQ;
17601470923Sjmcneill }
17701470923Sjmcneill
178*8d564c5dSskrll static const struct fdt_platform rk3288_platform = {
179*8d564c5dSskrll .fp_devmap = rk3288_platform_devmap,
180*8d564c5dSskrll .fp_bootstrap = rk3288_platform_bootstrap,
181*8d564c5dSskrll .fp_init_attach_args = rk_platform_init_attach_args,
182*8d564c5dSskrll .fp_device_register = rk_platform_device_register,
183*8d564c5dSskrll .fp_reset = rk3288_platform_reset,
184*8d564c5dSskrll .fp_delay = gtmr_delay,
185*8d564c5dSskrll .fp_uart_freq = rk3288_platform_uart_freq,
186*8d564c5dSskrll .fp_mpstart = arm_fdt_cpu_mpstart,
18701470923Sjmcneill };
18801470923Sjmcneill
189*8d564c5dSskrll FDT_PLATFORM(rk3288, "rockchip,rk3288", &rk3288_platform);
19001470923Sjmcneill #endif /* SOC_RK3288 */
19101470923Sjmcneill
19201470923Sjmcneill
1936726462dSjmcneill #ifdef SOC_RK3328
1946726462dSjmcneill
1956726462dSjmcneill #include <arm/rockchip/rk3328_platform.h>
1966726462dSjmcneill
1976726462dSjmcneill static const struct pmap_devmap *
rk3328_platform_devmap(void)1986726462dSjmcneill rk3328_platform_devmap(void)
1996726462dSjmcneill {
2006726462dSjmcneill static const struct pmap_devmap devmap[] = {
2016726462dSjmcneill DEVMAP_ENTRY(RK3328_CORE_VBASE,
2026726462dSjmcneill RK3328_CORE_PBASE,
2036726462dSjmcneill RK3328_CORE_SIZE),
2046726462dSjmcneill DEVMAP_ENTRY_END
2056726462dSjmcneill };
2066726462dSjmcneill
2076726462dSjmcneill return devmap;
2086726462dSjmcneill }
2096726462dSjmcneill
2106726462dSjmcneill void rk3328_platform_early_putchar(char);
2116726462dSjmcneill
212d329adb0Sskrll void __noasan
rk3328_platform_early_putchar(char c)2136726462dSjmcneill rk3328_platform_early_putchar(char c)
2146726462dSjmcneill {
2156726462dSjmcneill #ifdef CONSADDR
2166726462dSjmcneill #define CONSADDR_VA ((CONSADDR - RK3328_CORE_PBASE) + RK3328_CORE_VBASE)
2176726462dSjmcneill volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
2186726462dSjmcneill (volatile uint32_t *)CONSADDR_VA :
2196726462dSjmcneill (volatile uint32_t *)CONSADDR;
2206726462dSjmcneill
2216726462dSjmcneill while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
2226726462dSjmcneill ;
2236726462dSjmcneill
2246726462dSjmcneill uartaddr[com_data] = htole32(c);
2256726462dSjmcneill #undef CONSADDR_VA
2266726462dSjmcneill #endif
2276726462dSjmcneill }
2286726462dSjmcneill
2296726462dSjmcneill static u_int
rk3328_platform_uart_freq(void)2306726462dSjmcneill rk3328_platform_uart_freq(void)
2316726462dSjmcneill {
2326726462dSjmcneill return RK3328_UART_FREQ;
2336726462dSjmcneill }
2346726462dSjmcneill
235*8d564c5dSskrll static const struct fdt_platform rk3328_platform = {
236*8d564c5dSskrll .fp_devmap = rk3328_platform_devmap,
237*8d564c5dSskrll .fp_bootstrap = rk_platform_bootstrap,
238*8d564c5dSskrll .fp_init_attach_args = rk_platform_init_attach_args,
239*8d564c5dSskrll .fp_device_register = rk_platform_device_register,
240*8d564c5dSskrll .fp_reset = psci_fdt_reset,
241*8d564c5dSskrll .fp_delay = gtmr_delay,
242*8d564c5dSskrll .fp_uart_freq = rk3328_platform_uart_freq,
243*8d564c5dSskrll .fp_mpstart = arm_fdt_cpu_mpstart,
2446726462dSjmcneill };
2456726462dSjmcneill
246*8d564c5dSskrll FDT_PLATFORM(rk3328, "rockchip,rk3328", &rk3328_platform);
2476726462dSjmcneill
2486726462dSjmcneill #endif /* SOC_RK3328 */
2498c7bec30Sjmcneill
2508c7bec30Sjmcneill
2518c7bec30Sjmcneill #ifdef SOC_RK3399
2528c7bec30Sjmcneill
2538c7bec30Sjmcneill #include <arm/rockchip/rk3399_platform.h>
2548c7bec30Sjmcneill
2558c7bec30Sjmcneill static const struct pmap_devmap *
rk3399_platform_devmap(void)2568c7bec30Sjmcneill rk3399_platform_devmap(void)
2578c7bec30Sjmcneill {
2588c7bec30Sjmcneill static const struct pmap_devmap devmap[] = {
2598c7bec30Sjmcneill DEVMAP_ENTRY(RK3399_CORE_VBASE,
2608c7bec30Sjmcneill RK3399_CORE_PBASE,
2618c7bec30Sjmcneill RK3399_CORE_SIZE),
2628c7bec30Sjmcneill DEVMAP_ENTRY_END
2638c7bec30Sjmcneill };
2648c7bec30Sjmcneill
2658c7bec30Sjmcneill return devmap;
2668c7bec30Sjmcneill }
2678c7bec30Sjmcneill
2688c7bec30Sjmcneill void rk3399_platform_early_putchar(char);
2698c7bec30Sjmcneill
2708c7bec30Sjmcneill void
rk3399_platform_early_putchar(char c)2718c7bec30Sjmcneill rk3399_platform_early_putchar(char c)
2728c7bec30Sjmcneill {
2738c7bec30Sjmcneill #ifdef CONSADDR
2748c7bec30Sjmcneill #define CONSADDR_VA ((CONSADDR - RK3399_CORE_PBASE) + RK3399_CORE_VBASE)
2758c7bec30Sjmcneill volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
2768c7bec30Sjmcneill (volatile uint32_t *)CONSADDR_VA :
2778c7bec30Sjmcneill (volatile uint32_t *)CONSADDR;
2788c7bec30Sjmcneill
2798c7bec30Sjmcneill while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
2808c7bec30Sjmcneill ;
2818c7bec30Sjmcneill
2828c7bec30Sjmcneill uartaddr[com_data] = htole32(c);
2838c7bec30Sjmcneill #undef CONSADDR_VA
2848c7bec30Sjmcneill #endif
2858c7bec30Sjmcneill }
2868c7bec30Sjmcneill
2878c7bec30Sjmcneill static u_int
rk3399_platform_uart_freq(void)2888c7bec30Sjmcneill rk3399_platform_uart_freq(void)
2898c7bec30Sjmcneill {
2908c7bec30Sjmcneill return RK3399_UART_FREQ;
2918c7bec30Sjmcneill }
2928c7bec30Sjmcneill
293*8d564c5dSskrll static const struct fdt_platform rk3399_platform = {
294*8d564c5dSskrll .fp_devmap = rk3399_platform_devmap,
295*8d564c5dSskrll .fp_bootstrap = rk_platform_bootstrap,
296*8d564c5dSskrll .fp_init_attach_args = rk_platform_init_attach_args,
297*8d564c5dSskrll .fp_device_register = rk_platform_device_register,
298*8d564c5dSskrll .fp_reset = psci_fdt_reset,
299*8d564c5dSskrll .fp_delay = gtmr_delay,
300*8d564c5dSskrll .fp_uart_freq = rk3399_platform_uart_freq,
301*8d564c5dSskrll .fp_mpstart = arm_fdt_cpu_mpstart,
3028c7bec30Sjmcneill };
3038c7bec30Sjmcneill
304*8d564c5dSskrll FDT_PLATFORM(rk3399, "rockchip,rk3399", &rk3399_platform);
3058c7bec30Sjmcneill
3068c7bec30Sjmcneill #endif /* SOC_RK3399 */
3074fb05369Sryo
3084fb05369Sryo
3094fb05369Sryo #ifdef SOC_RK3588
3104fb05369Sryo
3114fb05369Sryo #include <arm/rockchip/rk3588_platform.h>
3124fb05369Sryo
3134fb05369Sryo static const struct pmap_devmap *
rk3588_platform_devmap(void)3144fb05369Sryo rk3588_platform_devmap(void)
3154fb05369Sryo {
3164fb05369Sryo static const struct pmap_devmap devmap[] = {
3174fb05369Sryo DEVMAP_ENTRY(
3184fb05369Sryo RK3588_CORE_VBASE,
3194fb05369Sryo RK3588_CORE_PBASE,
3204fb05369Sryo RK3588_CORE_SIZE),
3214fb05369Sryo DEVMAP_ENTRY_END
3224fb05369Sryo };
3234fb05369Sryo
3244fb05369Sryo return devmap;
3254fb05369Sryo }
3264fb05369Sryo
3274fb05369Sryo void rk3588_platform_early_putchar(char);
3284fb05369Sryo
3294fb05369Sryo void
rk3588_platform_early_putchar(char c)3304fb05369Sryo rk3588_platform_early_putchar(char c)
3314fb05369Sryo {
3324fb05369Sryo #ifdef CONSADDR
3334fb05369Sryo #define CONSADDR_VA ((CONSADDR - RK3588_CORE_PBASE) + RK3588_CORE_VBASE)
3344fb05369Sryo volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
3354fb05369Sryo (volatile uint32_t *)CONSADDR_VA :
3364fb05369Sryo (volatile uint32_t *)CONSADDR;
3374fb05369Sryo
3384fb05369Sryo while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
3394fb05369Sryo ;
3404fb05369Sryo
3414fb05369Sryo uartaddr[com_data] = htole32(c);
3424fb05369Sryo #undef CONSADDR_VA
3434fb05369Sryo #endif
3444fb05369Sryo }
3454fb05369Sryo
3464fb05369Sryo static u_int
rk3588_platform_uart_freq(void)3474fb05369Sryo rk3588_platform_uart_freq(void)
3484fb05369Sryo {
3494fb05369Sryo return RK3588_UART_FREQ;
3504fb05369Sryo }
3514fb05369Sryo
352*8d564c5dSskrll static const struct fdt_platform rk3588_platform = {
353*8d564c5dSskrll .fp_devmap = rk3588_platform_devmap,
354*8d564c5dSskrll .fp_bootstrap = rk_platform_bootstrap,
355*8d564c5dSskrll .fp_init_attach_args = rk_platform_init_attach_args,
356*8d564c5dSskrll .fp_device_register = rk_platform_device_register,
357*8d564c5dSskrll .fp_reset = psci_fdt_reset,
358*8d564c5dSskrll .fp_delay = gtmr_delay,
359*8d564c5dSskrll .fp_uart_freq = rk3588_platform_uart_freq,
360*8d564c5dSskrll .fp_mpstart = arm_fdt_cpu_mpstart,
3614fb05369Sryo };
3624fb05369Sryo
363*8d564c5dSskrll FDT_PLATFORM(rk3588, "rockchip,rk3588", &rk3588_platform);
3644fb05369Sryo
3654fb05369Sryo #endif /* SOC_RK3588 */
3664fb05369Sryo
367