Fri Jan 29 13:10:08 2021 UTC ()
Fix build without MULTIPROCESSOR.


(rin)
diff -r1.15 -r1.16 src/sys/arch/arm/altera/cycv_platform.c
diff -r1.16 -r1.17 src/sys/arch/arm/amlogic/meson_platform.c
diff -r1.2 -r1.3 src/sys/arch/arm/nxp/imx6_platform.c
diff -r1.11 -r1.12 src/sys/arch/arm/ti/ti_gpio.c

cvs diff -r1.15 -r1.16 src/sys/arch/arm/altera/cycv_platform.c (switch to unified diff)

--- src/sys/arch/arm/altera/cycv_platform.c 2020/11/27 07:11:49 1.15
+++ src/sys/arch/arm/altera/cycv_platform.c 2021/01/29 13:10:07 1.16
@@ -1,174 +1,177 @@ @@ -1,174 +1,177 @@
1/* $NetBSD: cycv_platform.c,v 1.15 2020/11/27 07:11:49 skrll Exp $ */ 1/* $NetBSD: cycv_platform.c,v 1.16 2021/01/29 13:10:07 rin Exp $ */
2 2
3/* This file is in the public domain. */ 3/* This file is in the public domain. */
4 4
5#include "arml2cc.h" 5#include "arml2cc.h"
6#include "opt_console.h" 6#include "opt_console.h"
7#include "opt_multiprocessor.h" 7#include "opt_multiprocessor.h"
8 8
9#include <sys/cdefs.h> 9#include <sys/cdefs.h>
10__KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.15 2020/11/27 07:11:49 skrll Exp $"); 10__KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.16 2021/01/29 13:10:07 rin Exp $");
11 11
12#define _ARM32_BUS_DMA_PRIVATE 12#define _ARM32_BUS_DMA_PRIVATE
13#include <sys/param.h> 13#include <sys/param.h>
14#include <sys/bus.h> 14#include <sys/bus.h>
15#include <sys/cpu.h> 15#include <sys/cpu.h>
16#include <sys/device.h> 16#include <sys/device.h>
17 17
18#include <uvm/uvm_extern.h> 18#include <uvm/uvm_extern.h>
19 19
20#include <arm/arm32/machdep.h> 20#include <arm/arm32/machdep.h>
21 21
22#include <arm/altera/cycv_reg.h> 22#include <arm/altera/cycv_reg.h>
23#include <arm/altera/cycv_var.h> 23#include <arm/altera/cycv_var.h>
24#include <arm/cortex/a9tmr_var.h> 24#include <arm/cortex/a9tmr_var.h>
25#include <arm/cortex/pl310_var.h> 25#include <arm/cortex/pl310_var.h>
26#include <arm/cortex/scu_reg.h> 26#include <arm/cortex/scu_reg.h>
27 27
28#include <arm/bootconfig.h> 28#include <arm/bootconfig.h>
29#include <arm/cpufunc.h> 29#include <arm/cpufunc.h>
30 30
31#include <arm/fdt/arm_fdtvar.h> 31#include <arm/fdt/arm_fdtvar.h>
32#include <dev/fdt/fdtvar.h> 32#include <dev/fdt/fdtvar.h>
33#include <dev/ic/comreg.h> 33#include <dev/ic/comreg.h>
34 34
35void cycv_platform_early_putchar(char); 35void cycv_platform_early_putchar(char);
36 36
37void __noasan 37void __noasan
38cycv_platform_early_putchar(char c) { 38cycv_platform_early_putchar(char c) {
39#ifdef CONSADDR 39#ifdef CONSADDR
40#define CONSADDR_VA (CONSADDR - CYCV_PERIPHERAL_BASE + CYCV_PERIPHERAL_VBASE) 40#define CONSADDR_VA (CONSADDR - CYCV_PERIPHERAL_BASE + CYCV_PERIPHERAL_VBASE)
41 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 41 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
42 (volatile uint32_t *) CONSADDR_VA : 42 (volatile uint32_t *) CONSADDR_VA :
43 (volatile uint32_t *) CONSADDR; 43 (volatile uint32_t *) CONSADDR;
44 44
45 while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0) 45 while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
46 ; 46 ;
47 47
48 uartaddr[com_data] = htole32(c); 48 uartaddr[com_data] = htole32(c);
49#endif 49#endif
50} 50}
51 51
52static const struct pmap_devmap * 52static const struct pmap_devmap *
53cycv_platform_devmap(void) { 53cycv_platform_devmap(void) {
54 static const struct pmap_devmap devmap[] = { 54 static const struct pmap_devmap devmap[] = {
55 DEVMAP_ENTRY(CYCV_PERIPHERAL_VBASE, 55 DEVMAP_ENTRY(CYCV_PERIPHERAL_VBASE,
56 CYCV_PERIPHERAL_BASE, 56 CYCV_PERIPHERAL_BASE,
57 CYCV_PERIPHERAL_SIZE), 57 CYCV_PERIPHERAL_SIZE),
58 DEVMAP_ENTRY_END 58 DEVMAP_ENTRY_END
59 }; 59 };
60 60
61 return devmap; 61 return devmap;
62} 62}
63 63
64static void 64static void
65cycv_platform_bootstrap(void) 65cycv_platform_bootstrap(void)
66{ 66{
67 bus_space_tag_t bst = &armv7_generic_bs_tag; 67 bus_space_tag_t bst = &armv7_generic_bs_tag;
68 bus_space_handle_t bsh_l2c; 68 bus_space_handle_t bsh_l2c;
69 69
70 bus_space_map(bst, CYCV_L2CACHE_BASE, CYCV_L2CACHE_SIZE, 0, &bsh_l2c); 70 bus_space_map(bst, CYCV_L2CACHE_BASE, CYCV_L2CACHE_SIZE, 0, &bsh_l2c);
71 71
72#if NARML2CC > 0 72#if NARML2CC > 0
73 arml2cc_init(bst, bsh_l2c, 0); 73 arml2cc_init(bst, bsh_l2c, 0);
74#endif 74#endif
75 75
76 arm_fdt_cpu_bootstrap(); 76 arm_fdt_cpu_bootstrap();
77} 77}
78 78
79static int 79static int
80cycv_mpstart(void) 80cycv_mpstart(void)
81{ 81{
 82 int ret = 0;
 83
 84#ifdef MULTIPROCESSOR
82 bus_space_tag_t bst = &armv7_generic_bs_tag; 85 bus_space_tag_t bst = &armv7_generic_bs_tag;
83 bus_space_handle_t bsh_rst; 86 bus_space_handle_t bsh_rst;
84 bus_space_handle_t bsh_scu; 87 bus_space_handle_t bsh_scu;
85 int ret = 0; 
86 88
87 bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh_rst); 89 bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh_rst);
88 bus_space_map(bst, CYCV_SCU_BASE, CYCV_SCU_SIZE, 0, &bsh_scu); 90 bus_space_map(bst, CYCV_SCU_BASE, CYCV_SCU_SIZE, 0, &bsh_scu);
89 91
90 /* Enable Snoop Control Unit */ 92 /* Enable Snoop Control Unit */
91 bus_space_write_4(bst, bsh_scu, SCU_INV_ALL_REG, 0xff); 93 bus_space_write_4(bst, bsh_scu, SCU_INV_ALL_REG, 0xff);
92 bus_space_write_4(bst, bsh_scu, SCU_CTL, 94 bus_space_write_4(bst, bsh_scu, SCU_CTL,
93 bus_space_read_4(bst, bsh_scu, SCU_CTL) | SCU_CTL_SCU_ENA); 95 bus_space_read_4(bst, bsh_scu, SCU_CTL) | SCU_CTL_SCU_ENA);
94 96
95 const uint32_t startfunc = 97 const uint32_t startfunc =
96 (uint32_t) KERN_VTOPHYS((vaddr_t) cpu_mpstart); 98 (uint32_t) KERN_VTOPHYS((vaddr_t) cpu_mpstart);
97 99
98 /* 100 /*
99 * We place a "LDR PC, =cpu_mpstart" at address 0 in order to bootstrap 101 * We place a "LDR PC, =cpu_mpstart" at address 0 in order to bootstrap
100 * CPU 1. We can't use the similar feature of the Boot ROM because 102 * CPU 1. We can't use the similar feature of the Boot ROM because
101 * it was unmapped by u-boot in favor of the SDRAM. 103 * it was unmapped by u-boot in favor of the SDRAM.
102 */ 104 */
103 pmap_map_chunk(kernel_l1pt.pv_va, CYCV_SDRAM_VBASE, CYCV_SDRAM_BASE, 105 pmap_map_chunk(kernel_l1pt.pv_va, CYCV_SDRAM_VBASE, CYCV_SDRAM_BASE,
104 L1_S_SIZE, VM_PROT_READ|VM_PROT_WRITE, PMAP_NOCACHE); 106 L1_S_SIZE, VM_PROT_READ|VM_PROT_WRITE, PMAP_NOCACHE);
105 107
106 /* 0: LDR PC, [PC, #0x18] -> loads address at 0x20 into PC */ 108 /* 0: LDR PC, [PC, #0x18] -> loads address at 0x20 into PC */
107 *(volatile uint32_t *) CYCV_SDRAM_VBASE = htole32(0xe59ff018); 109 *(volatile uint32_t *) CYCV_SDRAM_VBASE = htole32(0xe59ff018);
108 *(volatile uint32_t *) (CYCV_SDRAM_VBASE + 0x20) = startfunc; 110 *(volatile uint32_t *) (CYCV_SDRAM_VBASE + 0x20) = startfunc;
109 111
110 pmap_unmap_chunk(kernel_l1pt.pv_va, CYCV_SDRAM_VBASE, L1_S_SIZE); 112 pmap_unmap_chunk(kernel_l1pt.pv_va, CYCV_SDRAM_VBASE, L1_S_SIZE);
111 113
112 bus_space_write_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST, 114 bus_space_write_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST,
113 bus_space_read_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST) & 115 bus_space_read_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST) &
114 ~CYCV_RSTMGR_MPUMODRST_CPU1); 116 ~CYCV_RSTMGR_MPUMODRST_CPU1);
115 117
116 /* Wait for secondary processor to start */ 118 /* Wait for secondary processor to start */
117 int i; 119 int i;
118 for (i = 0x10000000; i > 0; i--) { 120 for (i = 0x10000000; i > 0; i--) {
119 if (cpu_hatched_p(1)) 121 if (cpu_hatched_p(1))
120 break; 122 break;
121 } 123 }
122 if (i == 0) { 124 if (i == 0) {
123 aprint_error("cpu%d: WARNING: AP failed to start\n", 1); 125 aprint_error("cpu%d: WARNING: AP failed to start\n", 1);
124 ret++; 126 ret++;
125 } 127 }
 128#endif
126 129
127 return ret; 130 return ret;
128} 131}
129 132
130static void 133static void
131cycv_platform_init_attach_args(struct fdt_attach_args *faa) { 134cycv_platform_init_attach_args(struct fdt_attach_args *faa) {
132 faa->faa_bst = &armv7_generic_bs_tag; 135 faa->faa_bst = &armv7_generic_bs_tag;
133 faa->faa_dmat = &arm_generic_dma_tag; 136 faa->faa_dmat = &arm_generic_dma_tag;
134} 137}
135 138
136static void 139static void
137cycv_platform_device_register(device_t dev, void *aux) { 140cycv_platform_device_register(device_t dev, void *aux) {
138 prop_dictionary_t dict = device_properties(dev); 141 prop_dictionary_t dict = device_properties(dev);
139 142
140 if (device_is_a(dev, "arma9tmr")) { 143 if (device_is_a(dev, "arma9tmr")) {
141 prop_dictionary_set_uint32(dict, "frequency", 144 prop_dictionary_set_uint32(dict, "frequency",
142 cycv_clkmgr_early_get_mpu_clk() / 4); 145 cycv_clkmgr_early_get_mpu_clk() / 4);
143 } 146 }
144} 147}
145 148
146static void 149static void
147cycv_platform_reset(void) { 150cycv_platform_reset(void) {
148 bus_space_tag_t bst = &armv7_generic_bs_tag; 151 bus_space_tag_t bst = &armv7_generic_bs_tag;
149 bus_space_handle_t bsh; 152 bus_space_handle_t bsh;
150 uint32_t val; 153 uint32_t val;
151 154
152 bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh); 155 bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh);
153 val = bus_space_read_4(bst, bsh, CYCV_RSTMGR_CTRL); 156 val = bus_space_read_4(bst, bsh, CYCV_RSTMGR_CTRL);
154 bus_space_write_4(bst, bsh, CYCV_RSTMGR_CTRL, 157 bus_space_write_4(bst, bsh, CYCV_RSTMGR_CTRL,
155 val | CYCV_RSTMGR_CTRL_SWCOLDRSTREQ); 158 val | CYCV_RSTMGR_CTRL_SWCOLDRSTREQ);
156} 159}
157 160
158static u_int 161static u_int
159cycv_platform_uart_freq(void) { 162cycv_platform_uart_freq(void) {
160 return cycv_clkmgr_early_get_l4_sp_clk(); 163 return cycv_clkmgr_early_get_l4_sp_clk();
161} 164}
162 165
163static const struct arm_platform cycv_platform = { 166static const struct arm_platform cycv_platform = {
164 .ap_devmap = cycv_platform_devmap, 167 .ap_devmap = cycv_platform_devmap,
165 .ap_bootstrap = cycv_platform_bootstrap, 168 .ap_bootstrap = cycv_platform_bootstrap,
166 .ap_init_attach_args = cycv_platform_init_attach_args, 169 .ap_init_attach_args = cycv_platform_init_attach_args,
167 .ap_device_register = cycv_platform_device_register, 170 .ap_device_register = cycv_platform_device_register,
168 .ap_reset = cycv_platform_reset, 171 .ap_reset = cycv_platform_reset,
169 .ap_delay = a9tmr_delay, 172 .ap_delay = a9tmr_delay,
170 .ap_uart_freq = cycv_platform_uart_freq, 173 .ap_uart_freq = cycv_platform_uart_freq,
171 .ap_mpstart = cycv_mpstart, 174 .ap_mpstart = cycv_mpstart,
172}; 175};
173 176
174ARM_PLATFORM(cycv, "altr,socfpga-cyclone5", &cycv_platform); 177ARM_PLATFORM(cycv, "altr,socfpga-cyclone5", &cycv_platform);

cvs diff -r1.16 -r1.17 src/sys/arch/arm/amlogic/meson_platform.c (switch to unified diff)

--- src/sys/arch/arm/amlogic/meson_platform.c 2020/09/28 11:54:22 1.16
+++ src/sys/arch/arm/amlogic/meson_platform.c 2021/01/29 13:10:07 1.17
@@ -1,494 +1,498 @@ @@ -1,494 +1,498 @@
1/* $NetBSD: meson_platform.c,v 1.16 2020/09/28 11:54:22 jmcneill Exp $ */ 1/* $NetBSD: meson_platform.c,v 1.17 2021/01/29 13:10:07 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_soc.h" 29#include "opt_soc.h"
30#include "opt_multiprocessor.h" 30#include "opt_multiprocessor.h"
31#include "opt_console.h" 31#include "opt_console.h"
32 32
33#include "arml2cc.h" 33#include "arml2cc.h"
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: meson_platform.c,v 1.16 2020/09/28 11:54:22 jmcneill Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: meson_platform.c,v 1.17 2021/01/29 13:10:07 rin Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40#include <sys/cpu.h> 40#include <sys/cpu.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/termios.h> 42#include <sys/termios.h>
43 43
44#include <dev/fdt/fdtvar.h> 44#include <dev/fdt/fdtvar.h>
45#include <arm/fdt/arm_fdtvar.h> 45#include <arm/fdt/arm_fdtvar.h>
46 46
47#include <uvm/uvm_extern.h> 47#include <uvm/uvm_extern.h>
48 48
49#include <machine/bootconfig.h> 49#include <machine/bootconfig.h>
50#include <arm/cpufunc.h> 50#include <arm/cpufunc.h>
51 51
52#include <arm/cortex/a9tmr_var.h> 52#include <arm/cortex/a9tmr_var.h>
53#include <arm/cortex/gtmr_var.h> 53#include <arm/cortex/gtmr_var.h>
54#include <arm/cortex/pl310_var.h> 54#include <arm/cortex/pl310_var.h>
55#include <arm/cortex/scu_reg.h> 55#include <arm/cortex/scu_reg.h>
56 56
57#include <arm/amlogic/meson_uart.h> 57#include <arm/amlogic/meson_uart.h>
58 58
59#include <evbarm/fdt/platform.h> 59#include <evbarm/fdt/platform.h>
60#include <evbarm/fdt/machdep.h> 60#include <evbarm/fdt/machdep.h>
61 61
62#include <net/if_ether.h> 62#include <net/if_ether.h>
63 63
64#include <libfdt.h> 64#include <libfdt.h>
65 65
66#define MESON_CORE_APB3_VBASE KERNEL_IO_VBASE 66#define MESON_CORE_APB3_VBASE KERNEL_IO_VBASE
67#define MESON_CORE_APB3_PBASE 0xc0000000 67#define MESON_CORE_APB3_PBASE 0xc0000000
68#define MESON_CORE_APB3_SIZE 0x01400000 68#define MESON_CORE_APB3_SIZE 0x01400000
69 69
70#define MESON_CBUS_OFFSET 0x01100000 70#define MESON_CBUS_OFFSET 0x01100000
71 71
72#define MESON8B_WATCHDOG_BASE 0xc1109900 72#define MESON8B_WATCHDOG_BASE 0xc1109900
73#define MESON8B_WATCHDOG_SIZE 0x8 73#define MESON8B_WATCHDOG_SIZE 0x8
74#define MESON8B_WATCHDOG_TC 0x00 74#define MESON8B_WATCHDOG_TC 0x00
75#define MESON8B_WATCHDOG_TC_CPUS __BITS(27,24) 75#define MESON8B_WATCHDOG_TC_CPUS __BITS(27,24)
76#define MESON8B_WATCHDOG_TC_ENABLE __BIT(19) 76#define MESON8B_WATCHDOG_TC_ENABLE __BIT(19)
77#define MESON8B_WATCHDOG_TC_TCNT __BITS(15,0) 77#define MESON8B_WATCHDOG_TC_TCNT __BITS(15,0)
78#define MESON8B_WATCHDOG_RESET 0x04 78#define MESON8B_WATCHDOG_RESET 0x04
79#define MESON8B_WATCHDOG_RESET_COUNT __BITS(15,0) 79#define MESON8B_WATCHDOG_RESET_COUNT __BITS(15,0)
80 80
81#define MESONGX_WATCHDOG_BASE 0xc11098d0 81#define MESONGX_WATCHDOG_BASE 0xc11098d0
82#define MESONGX_WATCHDOG_SIZE 0x10 82#define MESONGX_WATCHDOG_SIZE 0x10
83#define MESONGX_WATCHDOG_CNTL 0x00 83#define MESONGX_WATCHDOG_CNTL 0x00
84#define MESONGX_WATCHDOG_CNTL_CLK_EN __BIT(24) 84#define MESONGX_WATCHDOG_CNTL_CLK_EN __BIT(24)
85#define MESONGX_WATCHDOG_CNTL_SYS_RESET_N_EN __BIT(21) 85#define MESONGX_WATCHDOG_CNTL_SYS_RESET_N_EN __BIT(21)
86#define MESONGX_WATCHDOG_CNTL_WDOG_EN __BIT(18) 86#define MESONGX_WATCHDOG_CNTL_WDOG_EN __BIT(18)
87#define MESONGX_WATCHDOG_CNTL1 0x04 87#define MESONGX_WATCHDOG_CNTL1 0x04
88#define MESONGX_WATCHDOG_TCNT 0x08 88#define MESONGX_WATCHDOG_TCNT 0x08
89#define MESONGX_WATCHDOG_TCNT_COUNT __BITS(15,0) 89#define MESONGX_WATCHDOG_TCNT_COUNT __BITS(15,0)
90#define MESONGX_WATCHDOG_RESET 0x0c 90#define MESONGX_WATCHDOG_RESET 0x0c
91 91
92#define MESON8B_ARM_VBASE (MESON_CORE_APB3_VBASE + MESON_CORE_APB3_SIZE) 92#define MESON8B_ARM_VBASE (MESON_CORE_APB3_VBASE + MESON_CORE_APB3_SIZE)
93#define MESON8B_ARM_PBASE 0xc4200000 93#define MESON8B_ARM_PBASE 0xc4200000
94#define MESON8B_ARM_SIZE 0x00200000 94#define MESON8B_ARM_SIZE 0x00200000
95#define MESON8B_ARM_PL310_BASE 0x00000000 95#define MESON8B_ARM_PL310_BASE 0x00000000
96#define MESON8B_ARM_SCU_BASE 0x00100000 96#define MESON8B_ARM_SCU_BASE 0x00100000
97 97
98#define MESON8B_AOBUS_VBASE (MESON8B_ARM_VBASE + MESON8B_ARM_SIZE) 98#define MESON8B_AOBUS_VBASE (MESON8B_ARM_VBASE + MESON8B_ARM_SIZE)
99#define MESON8B_AOBUS_PBASE 0xc8000000 99#define MESON8B_AOBUS_PBASE 0xc8000000
100#define MESON8B_AOBUS_SIZE 0x00200000 100#define MESON8B_AOBUS_SIZE 0x00200000
101#define MESON8B_AOBUS_RTI_OFFSET 0x00100000 101#define MESON8B_AOBUS_RTI_OFFSET 0x00100000
102 102
103#define MESON_AOBUS_PWR_CTRL0_REG 0xe0 103#define MESON_AOBUS_PWR_CTRL0_REG 0xe0
104#define MESON_AOBUS_PWR_CTRL1_REG 0xe4 104#define MESON_AOBUS_PWR_CTRL1_REG 0xe4
105#define MESON_AOBUS_PWR_MEM_PD0_REG 0xf4 105#define MESON_AOBUS_PWR_MEM_PD0_REG 0xf4
106 106
107#define MESON_CBUS_CPU_CLK_CNTL_REG 0x419c 107#define MESON_CBUS_CPU_CLK_CNTL_REG 0x419c
108 108
109 109
110#define MESON8B_SRAM_VBASE (MESON8B_AOBUS_VBASE + MESON8B_AOBUS_SIZE) 110#define MESON8B_SRAM_VBASE (MESON8B_AOBUS_VBASE + MESON8B_AOBUS_SIZE)
111#define MESON8B_SRAM_PBASE 0xd9000000 111#define MESON8B_SRAM_PBASE 0xd9000000
112#define MESON8B_SRAM_SIZE 0x00200000 /* 0x10000 rounded up */ 112#define MESON8B_SRAM_SIZE 0x00200000 /* 0x10000 rounded up */
113 113
114#define MESON8B_SRAM_CPUCONF_OFFSET 0x1ff80 114#define MESON8B_SRAM_CPUCONF_OFFSET 0x1ff80
115#define MESON8B_SRAM_CPUCONF_CTRL_REG 0x00 115#define MESON8B_SRAM_CPUCONF_CTRL_REG 0x00
116#define MESON8B_SRAM_CPUCONF_CPU_ADDR_REG(n) (0x04 * (n)) 116#define MESON8B_SRAM_CPUCONF_CPU_ADDR_REG(n) (0x04 * (n))
117 117
118 118
119extern struct arm32_bus_dma_tag arm_generic_dma_tag; 119extern struct arm32_bus_dma_tag arm_generic_dma_tag;
120extern struct bus_space arm_generic_bs_tag; 120extern struct bus_space arm_generic_bs_tag;
121 121
122#define meson_dma_tag arm_generic_dma_tag 122#define meson_dma_tag arm_generic_dma_tag
123#define meson_bs_tag arm_generic_bs_tag 123#define meson_bs_tag arm_generic_bs_tag
124 124
125static const struct pmap_devmap * 125static const struct pmap_devmap *
126meson_platform_devmap(void) 126meson_platform_devmap(void)
127{ 127{
128 static const struct pmap_devmap devmap[] = { 128 static const struct pmap_devmap devmap[] = {
129 DEVMAP_ENTRY(MESON_CORE_APB3_VBASE, 129 DEVMAP_ENTRY(MESON_CORE_APB3_VBASE,
130 MESON_CORE_APB3_PBASE, 130 MESON_CORE_APB3_PBASE,
131 MESON_CORE_APB3_SIZE), 131 MESON_CORE_APB3_SIZE),
132 DEVMAP_ENTRY(MESON8B_ARM_VBASE, 132 DEVMAP_ENTRY(MESON8B_ARM_VBASE,
133 MESON8B_ARM_PBASE, 133 MESON8B_ARM_PBASE,
134 MESON8B_ARM_SIZE), 134 MESON8B_ARM_SIZE),
135 DEVMAP_ENTRY(MESON8B_AOBUS_VBASE, 135 DEVMAP_ENTRY(MESON8B_AOBUS_VBASE,
136 MESON8B_AOBUS_PBASE, 136 MESON8B_AOBUS_PBASE,
137 MESON8B_AOBUS_SIZE), 137 MESON8B_AOBUS_SIZE),
138 DEVMAP_ENTRY(MESON8B_SRAM_VBASE, 138 DEVMAP_ENTRY(MESON8B_SRAM_VBASE,
139 MESON8B_SRAM_PBASE, 139 MESON8B_SRAM_PBASE,
140 MESON8B_SRAM_SIZE), 140 MESON8B_SRAM_SIZE),
141 DEVMAP_ENTRY_END 141 DEVMAP_ENTRY_END
142 }; 142 };
143 143
144 return devmap; 144 return devmap;
145} 145}
146 146
147static void 147static void
148meson_platform_init_attach_args(struct fdt_attach_args *faa) 148meson_platform_init_attach_args(struct fdt_attach_args *faa)
149{ 149{
150 faa->faa_bst = &meson_bs_tag; 150 faa->faa_bst = &meson_bs_tag;
151 faa->faa_dmat = &meson_dma_tag; 151 faa->faa_dmat = &meson_dma_tag;
152} 152}
153 153
154void meson_platform_early_putchar(char); 154void meson_platform_early_putchar(char);
155 155
156void __noasan 156void __noasan
157meson_platform_early_putchar(char c) 157meson_platform_early_putchar(char c)
158{ 158{
159#ifdef CONSADDR 159#ifdef CONSADDR
160#define CONSADDR_VA ((CONSADDR - MESON8B_AOBUS_PBASE) + MESON8B_AOBUS_VBASE) 160#define CONSADDR_VA ((CONSADDR - MESON8B_AOBUS_PBASE) + MESON8B_AOBUS_VBASE)
161 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 161 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
162 (volatile uint32_t *)CONSADDR_VA : 162 (volatile uint32_t *)CONSADDR_VA :
163 (volatile uint32_t *)CONSADDR; 163 (volatile uint32_t *)CONSADDR;
164 int timo = 150000; 164 int timo = 150000;
165 165
166 while ((uartaddr[UART_STATUS_REG/4] & UART_STATUS_TX_EMPTY) == 0) { 166 while ((uartaddr[UART_STATUS_REG/4] & UART_STATUS_TX_EMPTY) == 0) {
167 if (--timo == 0) 167 if (--timo == 0)
168 break; 168 break;
169 } 169 }
170 170
171 uartaddr[UART_WFIFO_REG/4] = c; 171 uartaddr[UART_WFIFO_REG/4] = c;
172 172
173 while ((uartaddr[UART_STATUS_REG/4] & UART_STATUS_TX_EMPTY) == 0) { 173 while ((uartaddr[UART_STATUS_REG/4] & UART_STATUS_TX_EMPTY) == 0) {
174 if (--timo == 0) 174 if (--timo == 0)
175 break; 175 break;
176 } 176 }
177#endif 177#endif
178} 178}
179 179
180static void 180static void
181meson_platform_device_register(device_t self, void *aux) 181meson_platform_device_register(device_t self, void *aux)
182{ 182{
183 prop_dictionary_t dict = device_properties(self); 183 prop_dictionary_t dict = device_properties(self);
184 184
185 if (device_is_a(self, "awge") && device_unit(self) == 0) { 185 if (device_is_a(self, "awge") && device_unit(self) == 0) {
186 uint8_t enaddr[ETHER_ADDR_LEN]; 186 uint8_t enaddr[ETHER_ADDR_LEN];
187 if (get_bootconf_option(boot_args, "awge0.mac-address", 187 if (get_bootconf_option(boot_args, "awge0.mac-address",
188 BOOTOPT_TYPE_MACADDR, enaddr)) { 188 BOOTOPT_TYPE_MACADDR, enaddr)) {
189 prop_dictionary_set_data(dict, "mac-address", enaddr, 189 prop_dictionary_set_data(dict, "mac-address", enaddr,
190 sizeof(enaddr)); 190 sizeof(enaddr));
191 } 191 }
192 } 192 }
193 193
194 if (device_is_a(self, "mesonfb")) { 194 if (device_is_a(self, "mesonfb")) {
195 int scale, depth; 195 int scale, depth;
196 196
197 if (get_bootconf_option(boot_args, "fb.scale", 197 if (get_bootconf_option(boot_args, "fb.scale",
198 BOOTOPT_TYPE_INT, &scale) && scale > 0) { 198 BOOTOPT_TYPE_INT, &scale) && scale > 0) {
199 prop_dictionary_set_uint32(dict, "scale", scale); 199 prop_dictionary_set_uint32(dict, "scale", scale);
200 } 200 }
201 if (get_bootconf_option(boot_args, "fb.depth", 201 if (get_bootconf_option(boot_args, "fb.depth",
202 BOOTOPT_TYPE_INT, &depth)) { 202 BOOTOPT_TYPE_INT, &depth)) {
203 prop_dictionary_set_uint32(dict, "depth", depth); 203 prop_dictionary_set_uint32(dict, "depth", depth);
204 } 204 }
205 } 205 }
206} 206}
207 207
208#if defined(SOC_MESON8B) 208#if defined(SOC_MESON8B)
209#define MESON8B_BOOTINFO_REG 0xd901ff04 209#define MESON8B_BOOTINFO_REG 0xd901ff04
210static int 210static int
211meson8b_get_boot_id(void) 211meson8b_get_boot_id(void)
212{ 212{
213 static int boot_id = -1; 213 static int boot_id = -1;
214 bus_space_tag_t bst = &arm_generic_bs_tag; 214 bus_space_tag_t bst = &arm_generic_bs_tag;
215 bus_space_handle_t bsh; 215 bus_space_handle_t bsh;
216 216
217 if (boot_id == -1) { 217 if (boot_id == -1) {
218 if (bus_space_map(bst, MESON8B_BOOTINFO_REG, 4, 0, &bsh) != 0) 218 if (bus_space_map(bst, MESON8B_BOOTINFO_REG, 4, 0, &bsh) != 0)
219 return -1; 219 return -1;
220 220
221 boot_id = (int)bus_space_read_4(bst, bsh, 0); 221 boot_id = (int)bus_space_read_4(bst, bsh, 0);
222 222
223 bus_space_unmap(bst, bsh, 4); 223 bus_space_unmap(bst, bsh, 4);
224 } 224 }
225 225
226 return boot_id; 226 return boot_id;
227} 227}
228 228
229static void 229static void
230meson8b_platform_device_register(device_t self, void *aux) 230meson8b_platform_device_register(device_t self, void *aux)
231{ 231{
232 device_t parent = device_parent(self); 232 device_t parent = device_parent(self);
233 char *ptr; 233 char *ptr;
234 234
235 if (device_is_a(self, "ld") && 235 if (device_is_a(self, "ld") &&
236 device_is_a(parent, "sdmmc") && 236 device_is_a(parent, "sdmmc") &&
237 (device_is_a(device_parent(parent), "mesonsdhc") || 237 (device_is_a(device_parent(parent), "mesonsdhc") ||
238 device_is_a(device_parent(parent), "mesonsdio"))) { 238 device_is_a(device_parent(parent), "mesonsdio"))) {
239 239
240 const int boot_id = meson8b_get_boot_id(); 240 const int boot_id = meson8b_get_boot_id();
241 const bool has_rootdev = get_bootconf_option(boot_args, "root", BOOTOPT_TYPE_STRING, &ptr) != 0; 241 const bool has_rootdev = get_bootconf_option(boot_args, "root", BOOTOPT_TYPE_STRING, &ptr) != 0;
242 242
243 if (!has_rootdev) { 243 if (!has_rootdev) {
244 char rootarg[64]; 244 char rootarg[64];
245 snprintf(rootarg, sizeof(rootarg), " root=%sa", device_xname(self)); 245 snprintf(rootarg, sizeof(rootarg), " root=%sa", device_xname(self));
246 246
247 /* Assume that SDIO is used for SD cards and SDHC is used for eMMC */ 247 /* Assume that SDIO is used for SD cards and SDHC is used for eMMC */
248 if (device_is_a(device_parent(parent), "mesonsdhc") && boot_id == 0) 248 if (device_is_a(device_parent(parent), "mesonsdhc") && boot_id == 0)
249 strcat(boot_args, rootarg); 249 strcat(boot_args, rootarg);
250 else if (device_is_a(device_parent(parent), "mesonsdio") && boot_id != 0) 250 else if (device_is_a(device_parent(parent), "mesonsdio") && boot_id != 0)
251 strcat(boot_args, rootarg); 251 strcat(boot_args, rootarg);
252 } 252 }
253 } 253 }
254 254
255 meson_platform_device_register(self, aux); 255 meson_platform_device_register(self, aux);
256} 256}
257#endif 257#endif
258 258
259static u_int 259static u_int
260meson_platform_uart_freq(void) 260meson_platform_uart_freq(void)
261{ 261{
262 return 0; 262 return 0;
263} 263}
264 264
265static void 265static void
266meson_platform_bootstrap(void) 266meson_platform_bootstrap(void)
267{ 267{
268 arm_fdt_cpu_bootstrap(); 268 arm_fdt_cpu_bootstrap();
269 269
270 void *fdt_data = __UNCONST(fdtbus_get_data()); 270 void *fdt_data = __UNCONST(fdtbus_get_data());
271 const int chosen_off = fdt_path_offset(fdt_data, "/chosen"); 271 const int chosen_off = fdt_path_offset(fdt_data, "/chosen");
272 if (chosen_off < 0) 272 if (chosen_off < 0)
273 return; 273 return;
274 274
275 if (match_bootconf_option(boot_args, "console", "fb")) { 275 if (match_bootconf_option(boot_args, "console", "fb")) {
276 const int framebuffer_off = 276 const int framebuffer_off =
277 fdt_path_offset(fdt_data, "/chosen/framebuffer"); 277 fdt_path_offset(fdt_data, "/chosen/framebuffer");
278 if (framebuffer_off >= 0) { 278 if (framebuffer_off >= 0) {
279 const char *status = fdt_getprop(fdt_data, 279 const char *status = fdt_getprop(fdt_data,
280 framebuffer_off, "status", NULL); 280 framebuffer_off, "status", NULL);
281 if (status == NULL || strncmp(status, "ok", 2) == 0) { 281 if (status == NULL || strncmp(status, "ok", 2) == 0) {
282 fdt_setprop_string(fdt_data, chosen_off, 282 fdt_setprop_string(fdt_data, chosen_off,
283 "stdout-path", "/chosen/framebuffer"); 283 "stdout-path", "/chosen/framebuffer");
284 } 284 }
285 } 285 }
286 } else if (match_bootconf_option(boot_args, "console", "serial")) { 286 } else if (match_bootconf_option(boot_args, "console", "serial")) {
287 fdt_setprop_string(fdt_data, chosen_off, 287 fdt_setprop_string(fdt_data, chosen_off,
288 "stdout-path", "serial0:115200n8"); 288 "stdout-path", "serial0:115200n8");
289 } 289 }
290} 290}
291 291
292#if defined(SOC_MESON8B) 292#if defined(SOC_MESON8B)
293static void 293static void
294meson8b_platform_bootstrap(void) 294meson8b_platform_bootstrap(void)
295{ 295{
296 296
297#if NARML2CC > 0 297#if NARML2CC > 0
298 const bus_space_handle_t pl310_bh = MESON8B_ARM_VBASE + MESON8B_ARM_PL310_BASE; 298 const bus_space_handle_t pl310_bh = MESON8B_ARM_VBASE + MESON8B_ARM_PL310_BASE;
299 arml2cc_init(&arm_generic_bs_tag, pl310_bh, 0); 299 arml2cc_init(&arm_generic_bs_tag, pl310_bh, 0);
300#endif 300#endif
301 301
302 meson_platform_bootstrap(); 302 meson_platform_bootstrap();
303} 303}
304 304
305static void 305static void
306meson8b_platform_reset(void) 306meson8b_platform_reset(void)
307{ 307{
308 bus_space_tag_t bst = &meson_bs_tag; 308 bus_space_tag_t bst = &meson_bs_tag;
309 bus_space_handle_t bsh; 309 bus_space_handle_t bsh;
310 310
311 bus_space_map(bst, MESON8B_WATCHDOG_BASE, MESON8B_WATCHDOG_SIZE, 0, &bsh); 311 bus_space_map(bst, MESON8B_WATCHDOG_BASE, MESON8B_WATCHDOG_SIZE, 0, &bsh);
312 312
313 bus_space_write_4(bst, bsh, MESON8B_WATCHDOG_TC, 313 bus_space_write_4(bst, bsh, MESON8B_WATCHDOG_TC,
314 MESON8B_WATCHDOG_TC_CPUS | MESON8B_WATCHDOG_TC_ENABLE | __SHIFTIN(0xfff, MESON8B_WATCHDOG_TC_TCNT)); 314 MESON8B_WATCHDOG_TC_CPUS | MESON8B_WATCHDOG_TC_ENABLE | __SHIFTIN(0xfff, MESON8B_WATCHDOG_TC_TCNT));
315 bus_space_write_4(bst, bsh, MESON8B_WATCHDOG_RESET, 0); 315 bus_space_write_4(bst, bsh, MESON8B_WATCHDOG_RESET, 0);
316 316
317 for (;;) { 317 for (;;) {
318 __asm("wfi"); 318 __asm("wfi");
319 } 319 }
320} 320}
321 321
 322#ifdef MULTIPROCESSOR
322static void 323static void
323meson8b_mpinit_delay(u_int n) 324meson8b_mpinit_delay(u_int n)
324{ 325{
325 for (volatile int i = 0; i < n; i++) 326 for (volatile int i = 0; i < n; i++)
326 ; 327 ;
327} 328}
 329#endif
328 330
329static int 331static int
330cpu_enable_meson8b(int phandle) 332cpu_enable_meson8b(int phandle)
331{ 333{
 334#ifdef MULTIPROCESSOR
332 const bus_addr_t cbar = armreg_cbar_read(); 335 const bus_addr_t cbar = armreg_cbar_read();
333 bus_space_tag_t bst = &arm_generic_bs_tag; 336 bus_space_tag_t bst = &arm_generic_bs_tag;
334 337
335 const bus_space_handle_t scu_bsh = 338 const bus_space_handle_t scu_bsh =
336 cbar - MESON8B_ARM_PBASE + MESON8B_ARM_VBASE; 339 cbar - MESON8B_ARM_PBASE + MESON8B_ARM_VBASE;
337 const bus_space_handle_t cpuconf_bsh = 340 const bus_space_handle_t cpuconf_bsh =
338 MESON8B_SRAM_VBASE + MESON8B_SRAM_CPUCONF_OFFSET; 341 MESON8B_SRAM_VBASE + MESON8B_SRAM_CPUCONF_OFFSET;
339 const bus_space_handle_t ao_bsh = 342 const bus_space_handle_t ao_bsh =
340 MESON8B_AOBUS_VBASE + MESON8B_AOBUS_RTI_OFFSET; 343 MESON8B_AOBUS_VBASE + MESON8B_AOBUS_RTI_OFFSET;
341 const bus_space_handle_t cbus_bsh = 344 const bus_space_handle_t cbus_bsh =
342 MESON_CORE_APB3_VBASE + MESON_CBUS_OFFSET; 345 MESON_CORE_APB3_VBASE + MESON_CBUS_OFFSET;
343 uint32_t pwr_sts, pwr_cntl0, pwr_cntl1, cpuclk, mempd0; 346 uint32_t pwr_sts, pwr_cntl0, pwr_cntl1, cpuclk, mempd0;
344 uint64_t mpidr; 347 uint64_t mpidr;
345 348
346 fdtbus_get_reg64(phandle, 0, &mpidr, NULL); 349 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
347 350
348 const u_int cpuno = __SHIFTOUT(mpidr, MPIDR_AFF0); 351 const u_int cpuno = __SHIFTOUT(mpidr, MPIDR_AFF0);
349 352
350 bus_space_write_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CPU_ADDR_REG(cpuno), 353 bus_space_write_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CPU_ADDR_REG(cpuno),
351 KERN_VTOPHYS((vaddr_t)cpu_mpstart)); 354 KERN_VTOPHYS((vaddr_t)cpu_mpstart));
352 355
353 pwr_sts = bus_space_read_4(bst, scu_bsh, SCU_CPU_PWR_STS); 356 pwr_sts = bus_space_read_4(bst, scu_bsh, SCU_CPU_PWR_STS);
354 pwr_sts &= ~(3 << (8 * cpuno)); 357 pwr_sts &= ~(3 << (8 * cpuno));
355 bus_space_write_4(bst, scu_bsh, SCU_CPU_PWR_STS, pwr_sts); 358 bus_space_write_4(bst, scu_bsh, SCU_CPU_PWR_STS, pwr_sts);
356 359
357 pwr_cntl0 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG); 360 pwr_cntl0 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG);
358 pwr_cntl0 &= ~((3 << 18) << ((cpuno - 1) * 2)); 361 pwr_cntl0 &= ~((3 << 18) << ((cpuno - 1) * 2));
359 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG, pwr_cntl0); 362 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG, pwr_cntl0);
360 363
361 meson8b_mpinit_delay(5000); 364 meson8b_mpinit_delay(5000);
362 365
363 cpuclk = bus_space_read_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG); 366 cpuclk = bus_space_read_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG);
364 cpuclk |= (1 << (24 + cpuno)); 367 cpuclk |= (1 << (24 + cpuno));
365 bus_space_write_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG, cpuclk); 368 bus_space_write_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG, cpuclk);
366 369
367 mempd0 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_MEM_PD0_REG); 370 mempd0 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_MEM_PD0_REG);
368 mempd0 &= ~((uint32_t)(0xf << 28) >> ((cpuno - 1) * 4)); 371 mempd0 &= ~((uint32_t)(0xf << 28) >> ((cpuno - 1) * 4));
369 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_MEM_PD0_REG, mempd0); 372 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_MEM_PD0_REG, mempd0);
370 373
371 pwr_cntl1 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL1_REG); 374 pwr_cntl1 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL1_REG);
372 pwr_cntl1 &= ~((3 << 4) << ((cpuno - 1) * 2)); 375 pwr_cntl1 &= ~((3 << 4) << ((cpuno - 1) * 2));
373 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL1_REG, pwr_cntl1); 376 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL1_REG, pwr_cntl1);
374 377
375 meson8b_mpinit_delay(10000); 378 meson8b_mpinit_delay(10000);
376 379
377 for (;;) { 380 for (;;) {
378 pwr_cntl1 = bus_space_read_4(bst, ao_bsh, 381 pwr_cntl1 = bus_space_read_4(bst, ao_bsh,
379 MESON_AOBUS_PWR_CTRL1_REG) & ((1 << 17) << (cpuno - 1)); 382 MESON_AOBUS_PWR_CTRL1_REG) & ((1 << 17) << (cpuno - 1));
380 if (pwr_cntl1) 383 if (pwr_cntl1)
381 break; 384 break;
382 meson8b_mpinit_delay(10000); 385 meson8b_mpinit_delay(10000);
383 } 386 }
384 387
385 pwr_cntl0 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG); 388 pwr_cntl0 = bus_space_read_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG);
386 pwr_cntl0 &= ~(1 << cpuno); 389 pwr_cntl0 &= ~(1 << cpuno);
387 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG, pwr_cntl0); 390 bus_space_write_4(bst, ao_bsh, MESON_AOBUS_PWR_CTRL0_REG, pwr_cntl0);
388 391
389 cpuclk = bus_space_read_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG); 392 cpuclk = bus_space_read_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG);
390 cpuclk &= ~(1 << (24 + cpuno)); 393 cpuclk &= ~(1 << (24 + cpuno));
391 bus_space_write_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG, cpuclk); 394 bus_space_write_4(bst, cbus_bsh, MESON_CBUS_CPU_CLK_CNTL_REG, cpuclk);
392 395
393 bus_space_write_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CPU_ADDR_REG(cpuno), 396 bus_space_write_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CPU_ADDR_REG(cpuno),
394 KERN_VTOPHYS((vaddr_t)cpu_mpstart)); 397 KERN_VTOPHYS((vaddr_t)cpu_mpstart));
395 398
396 uint32_t ctrl = bus_space_read_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CTRL_REG); 399 uint32_t ctrl = bus_space_read_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CTRL_REG);
397 ctrl |= __BITS(cpuno,0); 400 ctrl |= __BITS(cpuno,0);
398 bus_space_write_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CTRL_REG, ctrl); 401 bus_space_write_4(bst, cpuconf_bsh, MESON8B_SRAM_CPUCONF_CTRL_REG, ctrl);
 402#endif
399 403
400 return 0; 404 return 0;
401} 405}
402 406
403ARM_CPU_METHOD(meson8b, "amlogic,meson8b-smp", cpu_enable_meson8b); 407ARM_CPU_METHOD(meson8b, "amlogic,meson8b-smp", cpu_enable_meson8b);
404 408
405static int 409static int
406meson8b_mpstart(void) 410meson8b_mpstart(void)
407{ 411{
408 int ret = 0; 412 int ret = 0;
409 const bus_addr_t cbar = armreg_cbar_read(); 413 const bus_addr_t cbar = armreg_cbar_read();
410 bus_space_tag_t bst = &arm_generic_bs_tag; 414 bus_space_tag_t bst = &arm_generic_bs_tag;
411 415
412 if (cbar == 0) 416 if (cbar == 0)
413 return ret; 417 return ret;
414 418
415 const bus_space_handle_t scu_bsh = 419 const bus_space_handle_t scu_bsh =
416 cbar - MESON8B_ARM_PBASE + MESON8B_ARM_VBASE; 420 cbar - MESON8B_ARM_PBASE + MESON8B_ARM_VBASE;
417 421
418 const uint32_t scu_cfg = bus_space_read_4(bst, scu_bsh, SCU_CFG); 422 const uint32_t scu_cfg = bus_space_read_4(bst, scu_bsh, SCU_CFG);
419 const u_int ncpus = (scu_cfg & SCU_CFG_CPUMAX) + 1; 423 const u_int ncpus = (scu_cfg & SCU_CFG_CPUMAX) + 1;
420 424
421 if (ncpus < 2) 425 if (ncpus < 2)
422 return ret; 426 return ret;
423 427
424 /* 428 /*
425 * Invalidate all SCU cache tags. That is, for all cores (0-3) 429 * Invalidate all SCU cache tags. That is, for all cores (0-3)
426 */ 430 */
427 bus_space_write_4(bst, scu_bsh, SCU_INV_ALL_REG, 0xffff); 431 bus_space_write_4(bst, scu_bsh, SCU_INV_ALL_REG, 0xffff);
428 432
429 uint32_t scu_ctl = bus_space_read_4(bst, scu_bsh, SCU_CTL); 433 uint32_t scu_ctl = bus_space_read_4(bst, scu_bsh, SCU_CTL);
430 scu_ctl |= SCU_CTL_SCU_ENA; 434 scu_ctl |= SCU_CTL_SCU_ENA;
431 bus_space_write_4(bst, scu_bsh, SCU_CTL, scu_ctl); 435 bus_space_write_4(bst, scu_bsh, SCU_CTL, scu_ctl);
432 436
433 armv7_dcache_wbinv_all(); 437 armv7_dcache_wbinv_all();
434 438
435 ret = arm_fdt_cpu_mpstart(); 439 ret = arm_fdt_cpu_mpstart();
436 return ret; 440 return ret;
437} 441}
438 442
439static const struct arm_platform meson8b_platform = { 443static const struct arm_platform meson8b_platform = {
440 .ap_devmap = meson_platform_devmap, 444 .ap_devmap = meson_platform_devmap,
441 .ap_bootstrap = meson8b_platform_bootstrap, 445 .ap_bootstrap = meson8b_platform_bootstrap,
442 .ap_init_attach_args = meson_platform_init_attach_args, 446 .ap_init_attach_args = meson_platform_init_attach_args,
443 .ap_device_register = meson8b_platform_device_register, 447 .ap_device_register = meson8b_platform_device_register,
444 .ap_reset = meson8b_platform_reset, 448 .ap_reset = meson8b_platform_reset,
445 .ap_delay = a9ptmr_delay, 449 .ap_delay = a9ptmr_delay,
446 .ap_uart_freq = meson_platform_uart_freq, 450 .ap_uart_freq = meson_platform_uart_freq,
447 .ap_mpstart = meson8b_mpstart, 451 .ap_mpstart = meson8b_mpstart,
448}; 452};
449 453
450ARM_PLATFORM(meson8b, "amlogic,meson8b", &meson8b_platform); 454ARM_PLATFORM(meson8b, "amlogic,meson8b", &meson8b_platform);
451#endif /* SOC_MESON8B */ 455#endif /* SOC_MESON8B */
452 456
453#if defined(SOC_MESONGX) 457#if defined(SOC_MESONGX)
454static void 458static void
455mesongx_platform_reset(void) 459mesongx_platform_reset(void)
456{ 460{
457 bus_space_tag_t bst = &meson_bs_tag; 461 bus_space_tag_t bst = &meson_bs_tag;
458 bus_space_handle_t bsh; 462 bus_space_handle_t bsh;
459 uint32_t val; 463 uint32_t val;
460 464
461 bus_space_map(bst, MESONGX_WATCHDOG_BASE, MESONGX_WATCHDOG_SIZE, 0, &bsh); 465 bus_space_map(bst, MESONGX_WATCHDOG_BASE, MESONGX_WATCHDOG_SIZE, 0, &bsh);
462 466
463 val = MESONGX_WATCHDOG_CNTL_SYS_RESET_N_EN | 467 val = MESONGX_WATCHDOG_CNTL_SYS_RESET_N_EN |
464 MESONGX_WATCHDOG_CNTL_WDOG_EN | 468 MESONGX_WATCHDOG_CNTL_WDOG_EN |
465 MESONGX_WATCHDOG_CNTL_CLK_EN; 469 MESONGX_WATCHDOG_CNTL_CLK_EN;
466 bus_space_write_4(bst, bsh, MESONGX_WATCHDOG_CNTL, val); 470 bus_space_write_4(bst, bsh, MESONGX_WATCHDOG_CNTL, val);
467 471
468 bus_space_write_4(bst, bsh, MESONGX_WATCHDOG_TCNT, 1); 472 bus_space_write_4(bst, bsh, MESONGX_WATCHDOG_TCNT, 1);
469 473
470 bus_space_write_4(bst, bsh, MESONGX_WATCHDOG_RESET, 0); 474 bus_space_write_4(bst, bsh, MESONGX_WATCHDOG_RESET, 0);
471 475
472 for (;;) { 476 for (;;) {
473 __asm("wfi"); 477 __asm("wfi");
474 } 478 }
475} 479}
476 480
477static const struct arm_platform mesongx_platform = { 481static const struct arm_platform mesongx_platform = {
478 .ap_devmap = meson_platform_devmap, 482 .ap_devmap = meson_platform_devmap,
479 .ap_bootstrap = meson_platform_bootstrap, 483 .ap_bootstrap = meson_platform_bootstrap,
480 .ap_init_attach_args = meson_platform_init_attach_args, 484 .ap_init_attach_args = meson_platform_init_attach_args,
481 .ap_device_register = meson_platform_device_register, 485 .ap_device_register = meson_platform_device_register,
482 .ap_reset = mesongx_platform_reset, 486 .ap_reset = mesongx_platform_reset,
483 .ap_delay = gtmr_delay, 487 .ap_delay = gtmr_delay,
484 .ap_uart_freq = meson_platform_uart_freq, 488 .ap_uart_freq = meson_platform_uart_freq,
485 .ap_mpstart = arm_fdt_cpu_mpstart, 489 .ap_mpstart = arm_fdt_cpu_mpstart,
486}; 490};
487 491
488#if defined(SOC_MESONGXBB) 492#if defined(SOC_MESONGXBB)
489ARM_PLATFORM(mesongxbb, "amlogic,meson-gxbb", &mesongx_platform); 493ARM_PLATFORM(mesongxbb, "amlogic,meson-gxbb", &mesongx_platform);
490#endif /* SOC_MESONGXBB */ 494#endif /* SOC_MESONGXBB */
491#if defined(SOC_MESONGXL) 495#if defined(SOC_MESONGXL)
492ARM_PLATFORM(mesongxl, "amlogic,meson-gxl", &mesongx_platform); 496ARM_PLATFORM(mesongxl, "amlogic,meson-gxl", &mesongx_platform);
493#endif /* SOC_MESONGXL */ 497#endif /* SOC_MESONGXL */
494#endif /* SOC_MESONGX */ 498#endif /* SOC_MESONGX */

cvs diff -r1.2 -r1.3 src/sys/arch/arm/nxp/imx6_platform.c (switch to unified diff)

--- src/sys/arch/arm/nxp/imx6_platform.c 2021/01/27 03:10:20 1.2
+++ src/sys/arch/arm/nxp/imx6_platform.c 2021/01/29 13:10:07 1.3
@@ -1,236 +1,238 @@ @@ -1,236 +1,238 @@
1/* $NetBSD: imx6_platform.c,v 1.2 2021/01/27 03:10:20 thorpej Exp $ */ 1/* $NetBSD: imx6_platform.c,v 1.3 2021/01/29 13:10:07 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Genetec Corporation. All rights reserved. 4 * Copyright (c) 2019 Genetec Corporation. All rights reserved.
5 * Written by Hashimoto Kenichi for Genetec Corporation. 5 * Written by Hashimoto Kenichi for Genetec Corporation.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.2 2021/01/27 03:10:20 thorpej Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.3 2021/01/29 13:10:07 rin Exp $");
31 31
32#include "arml2cc.h" 32#include "arml2cc.h"
33#include "opt_console.h" 33#include "opt_console.h"
34#include "opt_fdt.h" 34#include "opt_fdt.h"
35#include "opt_multiprocessor.h" 35#include "opt_multiprocessor.h"
36#include "opt_soc.h" 36#include "opt_soc.h"
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40#include <sys/cpu.h> 40#include <sys/cpu.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/termios.h> 42#include <sys/termios.h>
43 43
44#include <dev/fdt/fdtvar.h> 44#include <dev/fdt/fdtvar.h>
45#include <arm/fdt/arm_fdtvar.h> 45#include <arm/fdt/arm_fdtvar.h>
46 46
47#include <uvm/uvm_extern.h> 47#include <uvm/uvm_extern.h>
48 48
49#include <arm/arm32/machdep.h> 49#include <arm/arm32/machdep.h>
50 50
51#include <machine/bootconfig.h> 51#include <machine/bootconfig.h>
52#include <arm/cpufunc.h> 52#include <arm/cpufunc.h>
53 53
54#include <arm/cortex/a9tmr_var.h> 54#include <arm/cortex/a9tmr_var.h>
55#include <arm/cortex/scu_reg.h> 55#include <arm/cortex/scu_reg.h>
56#include <arm/cortex/gic_reg.h> 56#include <arm/cortex/gic_reg.h>
57#include <arm/cortex/pl310_var.h> 57#include <arm/cortex/pl310_var.h>
58 58
59#include <arm/nxp/imx6_reg.h> 59#include <arm/nxp/imx6_reg.h>
60#include <arm/nxp/imx6_srcreg.h> 60#include <arm/nxp/imx6_srcreg.h>
61#include <arm/imx/imxuartreg.h> 61#include <arm/imx/imxuartreg.h>
62#include <arm/imx/imxwdogreg.h> 62#include <arm/imx/imxwdogreg.h>
63 63
64#include <arm/nxp/imx6_platform.h> 64#include <arm/nxp/imx6_platform.h>
65 65
66#include <libfdt.h> 66#include <libfdt.h>
67 67
68#define IMX_REF_FREQ 80000000 68#define IMX_REF_FREQ 80000000
69 69
70#ifdef VERBOSE_INIT_ARM 70#ifdef VERBOSE_INIT_ARM
71#define VPRINTF(...) printf(__VA_ARGS__) 71#define VPRINTF(...) printf(__VA_ARGS__)
72#else 72#else
73#define VPRINTF(...) __nothing 73#define VPRINTF(...) __nothing
74#endif 74#endif
75 75
76extern struct bus_space armv7_generic_bs_tag; 76extern struct bus_space armv7_generic_bs_tag;
77extern struct arm32_bus_dma_tag arm_generic_dma_tag; 77extern struct arm32_bus_dma_tag arm_generic_dma_tag;
78 78
79static const struct pmap_devmap * 79static const struct pmap_devmap *
80imx_platform_devmap(void) 80imx_platform_devmap(void)
81{ 81{
82 static const struct pmap_devmap devmap[] = { 82 static const struct pmap_devmap devmap[] = {
83 DEVMAP_ENTRY(KERNEL_IO_IOREG_VBASE, IMX6_IOREG_PBASE, IMX6_IOREG_SIZE), 83 DEVMAP_ENTRY(KERNEL_IO_IOREG_VBASE, IMX6_IOREG_PBASE, IMX6_IOREG_SIZE),
84 DEVMAP_ENTRY(KERNEL_IO_ARMCORE_VBASE, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE), 84 DEVMAP_ENTRY(KERNEL_IO_ARMCORE_VBASE, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE),
85 DEVMAP_ENTRY_END 85 DEVMAP_ENTRY_END
86 }; 86 };
87 87
88 return devmap; 88 return devmap;
89} 89}
90 90
91static void 91static void
92imx_platform_init_attach_args(struct fdt_attach_args *faa) 92imx_platform_init_attach_args(struct fdt_attach_args *faa)
93{ 93{
94 faa->faa_bst = &armv7_generic_bs_tag; 94 faa->faa_bst = &armv7_generic_bs_tag;
95 faa->faa_dmat = &arm_generic_dma_tag; 95 faa->faa_dmat = &arm_generic_dma_tag;
96} 96}
97 97
98void imx_platform_early_putchar(char); 98void imx_platform_early_putchar(char);
99 99
100void __noasan 100void __noasan
101imx_platform_early_putchar(char c) 101imx_platform_early_putchar(char c)
102{ 102{
103#ifdef CONSADDR 103#ifdef CONSADDR
104#define CONSADDR_VA ((CONSADDR - IMX6_IOREG_PBASE) + KERNEL_IO_IOREG_VBASE) 104#define CONSADDR_VA ((CONSADDR - IMX6_IOREG_PBASE) + KERNEL_IO_IOREG_VBASE)
105 105
106 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 106 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
107 (volatile uint32_t *)CONSADDR_VA : 107 (volatile uint32_t *)CONSADDR_VA :
108 (volatile uint32_t *)CONSADDR; 108 (volatile uint32_t *)CONSADDR;
109 109
110 while ((le32toh(uartaddr[(IMX_USR2/4)]) & IMX_USR2_TXDC) == 0) 110 while ((le32toh(uartaddr[(IMX_USR2/4)]) & IMX_USR2_TXDC) == 0)
111 ; 111 ;
112 112
113 uartaddr[(IMX_UTXD/4)] = htole32(c); 113 uartaddr[(IMX_UTXD/4)] = htole32(c);
114#endif 114#endif
115} 115}
116 116
117static void 117static void
118imx_platform_device_register(device_t self, void *aux) 118imx_platform_device_register(device_t self, void *aux)
119{ 119{
120 prop_dictionary_t prop = device_properties(self); 120 prop_dictionary_t prop = device_properties(self);
121 121
122 if (device_is_a(self, "atphy")) { 122 if (device_is_a(self, "atphy")) {
123 static const struct device_compatible_entry compat_data[] = { 123 static const struct device_compatible_entry compat_data[] = {
124 { .compat = "fsl,imx6dl-sabresd" }, 124 { .compat = "fsl,imx6dl-sabresd" },
125 { .compat = "fsl,imx6q-sabresd" }, 125 { .compat = "fsl,imx6q-sabresd" },
126 { .compat = "fsl,imx6qp-sabresd" }, 126 { .compat = "fsl,imx6qp-sabresd" },
127 { .compat = "solidrun,hummingboard2/q" }, 127 { .compat = "solidrun,hummingboard2/q" },
128 { .compat = "solidrun,hummingboard2/dl" }, 128 { .compat = "solidrun,hummingboard2/dl" },
129 DEVICE_COMPAT_EOL 129 DEVICE_COMPAT_EOL
130 }; 130 };
131 if (of_compatible_match(OF_finddevice("/"), compat_data)) 131 if (of_compatible_match(OF_finddevice("/"), compat_data))
132 prop_dictionary_set_uint32(prop, "clk_25m", 125000000); 132 prop_dictionary_set_uint32(prop, "clk_25m", 125000000);
133 } 133 }
134} 134}
135 135
136static u_int 136static u_int
137imx_platform_uart_freq(void) 137imx_platform_uart_freq(void)
138{ 138{
139 return IMX_REF_FREQ; 139 return IMX_REF_FREQ;
140} 140}
141 141
142static void 142static void
143imx_platform_bootstrap(void) 143imx_platform_bootstrap(void)
144{ 144{
145#if NARML2CC > 0 145#if NARML2CC > 0
146 bus_space_tag_t bst = &armv7_generic_bs_tag; 146 bus_space_tag_t bst = &armv7_generic_bs_tag;
147 bus_space_handle_t bsh; 147 bus_space_handle_t bsh;
148 if (bus_space_map(bst, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE, 0, &bsh)) 148 if (bus_space_map(bst, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE, 0, &bsh))
149 panic("couldn't map armcore registers"); 149 panic("couldn't map armcore registers");
150 arml2cc_init(bst, bsh, ARMCORE_L2C_BASE); 150 arml2cc_init(bst, bsh, ARMCORE_L2C_BASE);
151 bus_space_unmap(bst, bsh, IMX6_ARMCORE_SIZE); 151 bus_space_unmap(bst, bsh, IMX6_ARMCORE_SIZE);
152#endif 152#endif
153 153
154 arm_fdt_cpu_bootstrap(); 154 arm_fdt_cpu_bootstrap();
155} 155}
156 156
157static int 157static int
158imx_platform_mpstart(void) 158imx_platform_mpstart(void)
159{ 159{
160#if defined(MULTIPROCESSOR) 160#if defined(MULTIPROCESSOR)
161 bus_space_tag_t bst = &armv7_generic_bs_tag; 161 bus_space_tag_t bst = &armv7_generic_bs_tag;
162 bus_space_handle_t bsh; 162 bus_space_handle_t bsh;
163 163
164 if (bus_space_map(bst, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE, 0, &bsh) != 0) 164 if (bus_space_map(bst, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE, 0, &bsh) != 0)
165 panic("couldn't map armcore registers"); 165 panic("couldn't map armcore registers");
166 166
167 /* Enable Snoop Control Unit */ 167 /* Enable Snoop Control Unit */
168 bus_space_write_4(bst, bsh, SCU_INV_ALL_REG, 0xff); 168 bus_space_write_4(bst, bsh, SCU_INV_ALL_REG, 0xff);
169 bus_space_write_4(bst, bsh, SCU_CTL, 169 bus_space_write_4(bst, bsh, SCU_CTL,
170 bus_space_read_4(bst, bsh, SCU_CTL) | SCU_CTL_SCU_ENA); 170 bus_space_read_4(bst, bsh, SCU_CTL) | SCU_CTL_SCU_ENA);
171 171
172 bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE); 172 bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE);
173 173
174 if (bus_space_map(bst, IMX6_AIPS1_BASE + AIPS1_SRC_BASE, AIPS1_SRC_SIZE, 0, &bsh) != 0) 174 if (bus_space_map(bst, IMX6_AIPS1_BASE + AIPS1_SRC_BASE, AIPS1_SRC_SIZE, 0, &bsh) != 0)
175 panic("couldn't map SRC"); 175 panic("couldn't map SRC");
176 176
177 uint32_t srcctl = bus_space_read_4(bst, bsh, SRC_SCR); 177 uint32_t srcctl = bus_space_read_4(bst, bsh, SRC_SCR);
178 const paddr_t mpstart = KERN_VTOPHYS((vaddr_t)cpu_mpstart); 178 const paddr_t mpstart = KERN_VTOPHYS((vaddr_t)cpu_mpstart);
179 179
180 srcctl &= ~(SRC_SCR_CORE1_ENABLE | SRC_SCR_CORE2_ENABLE | 180 srcctl &= ~(SRC_SCR_CORE1_ENABLE | SRC_SCR_CORE2_ENABLE |
181 SRC_SCR_CORE3_ENABLE); 181 SRC_SCR_CORE3_ENABLE);
182 bus_space_write_4(bst, bsh, SRC_SCR, srcctl); 182 bus_space_write_4(bst, bsh, SRC_SCR, srcctl);
183 183
184 for (int i = 1; i < arm_cpu_max; i++) { 184 for (int i = 1; i < arm_cpu_max; i++) {
185 bus_space_write_4(bst, bsh, SRC_GPRN_ENTRY(i), mpstart); 185 bus_space_write_4(bst, bsh, SRC_GPRN_ENTRY(i), mpstart);
186 srcctl |= SRC_SCR_COREN_RST(i); 186 srcctl |= SRC_SCR_COREN_RST(i);
187 srcctl |= SRC_SCR_COREN_ENABLE(i); 187 srcctl |= SRC_SCR_COREN_ENABLE(i);
188 } 188 }
189 bus_space_write_4(bst, bsh, SRC_SCR, srcctl); 189 bus_space_write_4(bst, bsh, SRC_SCR, srcctl);
190 190
191 bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE); 191 bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE);
192 192
193 return arm_fdt_cpu_mpstart(); 193 return arm_fdt_cpu_mpstart();
 194#else
 195 return 0;
194#endif 196#endif
195} 197}
196 198
197static void 199static void
198imx6_platform_reset(void) 200imx6_platform_reset(void)
199{ 201{
200 bus_space_tag_t bst = &armv7_generic_bs_tag; 202 bus_space_tag_t bst = &armv7_generic_bs_tag;
201 bus_space_handle_t bsh; 203 bus_space_handle_t bsh;
202 204
203 if (bus_space_map(bst, IMX6_AIPS1_BASE + AIPS1_WDOG1_BASE, AIPS1_WDOG_SIZE, 0, &bsh)) 205 if (bus_space_map(bst, IMX6_AIPS1_BASE + AIPS1_WDOG1_BASE, AIPS1_WDOG_SIZE, 0, &bsh))
204 panic("couldn't map wdog1 registers"); 206 panic("couldn't map wdog1 registers");
205 207
206 delay(1000); /* wait for flushing FIFO of serial console */ 208 delay(1000); /* wait for flushing FIFO of serial console */
207 209
208 cpsid(I32_bit|F32_bit); 210 cpsid(I32_bit|F32_bit);
209 211
210 /* software reset signal on wdog */ 212 /* software reset signal on wdog */
211 bus_space_write_2(bst, bsh, IMX_WDOG_WCR, WCR_WDE); 213 bus_space_write_2(bst, bsh, IMX_WDOG_WCR, WCR_WDE);
212 214
213 /* 215 /*
214 * write twice due to errata. 216 * write twice due to errata.
215 * Reference: ERR004346: IMX6DQCE Chip Errata for the i.MX 6Dual/6Quad 217 * Reference: ERR004346: IMX6DQCE Chip Errata for the i.MX 6Dual/6Quad
216 */ 218 */
217 bus_space_write_2(bst, bsh, IMX_WDOG_WCR, WCR_WDE); 219 bus_space_write_2(bst, bsh, IMX_WDOG_WCR, WCR_WDE);
218 220
219 for (;;) 221 for (;;)
220 __asm("wfi"); 222 __asm("wfi");
221} 223}
222 224
223const struct arm_platform imx6_platform = { 225const struct arm_platform imx6_platform = {
224 .ap_devmap = imx_platform_devmap, 226 .ap_devmap = imx_platform_devmap,
225 .ap_bootstrap = imx_platform_bootstrap, 227 .ap_bootstrap = imx_platform_bootstrap,
226 .ap_init_attach_args = imx_platform_init_attach_args, 228 .ap_init_attach_args = imx_platform_init_attach_args,
227 .ap_device_register = imx_platform_device_register, 229 .ap_device_register = imx_platform_device_register,
228 .ap_reset = imx6_platform_reset, 230 .ap_reset = imx6_platform_reset,
229 .ap_delay = a9ptmr_delay, 231 .ap_delay = a9ptmr_delay,
230 .ap_uart_freq = imx_platform_uart_freq, 232 .ap_uart_freq = imx_platform_uart_freq,
231 .ap_mpstart = imx_platform_mpstart, 233 .ap_mpstart = imx_platform_mpstart,
232}; 234};
233 235
234ARM_PLATFORM(imx6dl, "fsl,imx6dl", &imx6_platform); 236ARM_PLATFORM(imx6dl, "fsl,imx6dl", &imx6_platform);
235ARM_PLATFORM(imx6q, "fsl,imx6q", &imx6_platform); 237ARM_PLATFORM(imx6q, "fsl,imx6q", &imx6_platform);
236ARM_PLATFORM(imx6qp, "fsl,imx6qp", &imx6_platform); 238ARM_PLATFORM(imx6qp, "fsl,imx6qp", &imx6_platform);

cvs diff -r1.11 -r1.12 src/sys/arch/arm/ti/ti_gpio.c (switch to unified diff)

--- src/sys/arch/arm/ti/ti_gpio.c 2021/01/29 13:07:32 1.11
+++ src/sys/arch/arm/ti/ti_gpio.c 2021/01/29 13:10:07 1.12
@@ -1,540 +1,541 @@ @@ -1,540 +1,541 @@
1/* $NetBSD: ti_gpio.c,v 1.11 2021/01/29 13:07:32 rin Exp $ */ 1/* $NetBSD: ti_gpio.c,v 1.12 2021/01/29 13:10:07 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 1.11 2021/01/29 13:07:32 rin Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 1.12 2021/01/29 13:10:07 rin Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bitops.h> 33#include <sys/bitops.h>
34#include <sys/bus.h> 34#include <sys/bus.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/gpio.h> 36#include <sys/gpio.h>
37#include <sys/intr.h> 37#include <sys/intr.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
 39#include <sys/lwp.h>
39#include <sys/mutex.h> 40#include <sys/mutex.h>
40#include <sys/systm.h> 41#include <sys/systm.h>
41 42
42#include <dev/fdt/fdtvar.h> 43#include <dev/fdt/fdtvar.h>
43#include <dev/gpio/gpiovar.h> 44#include <dev/gpio/gpiovar.h>
44 45
45#include <arm/ti/ti_prcm.h> 46#include <arm/ti/ti_prcm.h>
46 47
47#define TI_GPIO_NPINS 32 48#define TI_GPIO_NPINS 32
48 49
49enum ti_gpio_type { 50enum ti_gpio_type {
50 TI_GPIO_OMAP3, 51 TI_GPIO_OMAP3,
51 TI_GPIO_OMAP4, 52 TI_GPIO_OMAP4,
52 TI_NGPIO 53 TI_NGPIO
53}; 54};
54 55
55enum { 56enum {
56 GPIO_IRQSTATUS1, 57 GPIO_IRQSTATUS1,
57 GPIO_IRQENABLE1, /* OMAP3 */ 58 GPIO_IRQENABLE1, /* OMAP3 */
58 GPIO_IRQENABLE1_SET, /* OMAP4 */ 59 GPIO_IRQENABLE1_SET, /* OMAP4 */
59 GPIO_IRQENABLE1_CLR, /* OMAP4 */ 60 GPIO_IRQENABLE1_CLR, /* OMAP4 */
60 GPIO_OE, 61 GPIO_OE,
61 GPIO_DATAIN, 62 GPIO_DATAIN,
62 GPIO_DATAOUT, 63 GPIO_DATAOUT,
63 GPIO_LEVELDETECT0, 64 GPIO_LEVELDETECT0,
64 GPIO_LEVELDETECT1, 65 GPIO_LEVELDETECT1,
65 GPIO_RISINGDETECT, 66 GPIO_RISINGDETECT,
66 GPIO_FALLINGDETECT, 67 GPIO_FALLINGDETECT,
67 GPIO_CLEARDATAOUT, 68 GPIO_CLEARDATAOUT,
68 GPIO_SETDATAOUT, 69 GPIO_SETDATAOUT,
69 GPIO_NREG 70 GPIO_NREG
70}; 71};
71 72
72static const u_int ti_gpio_regmap[TI_NGPIO][GPIO_NREG] = { 73static const u_int ti_gpio_regmap[TI_NGPIO][GPIO_NREG] = {
73 [TI_GPIO_OMAP3] = { 74 [TI_GPIO_OMAP3] = {
74 [GPIO_IRQSTATUS1] = 0x18, 75 [GPIO_IRQSTATUS1] = 0x18,
75 [GPIO_IRQENABLE1] = 0x1c, 76 [GPIO_IRQENABLE1] = 0x1c,
76 [GPIO_OE] = 0x34, 77 [GPIO_OE] = 0x34,
77 [GPIO_DATAIN] = 0x38, 78 [GPIO_DATAIN] = 0x38,
78 [GPIO_DATAOUT] = 0x3c, 79 [GPIO_DATAOUT] = 0x3c,
79 [GPIO_LEVELDETECT0] = 0x40, 80 [GPIO_LEVELDETECT0] = 0x40,
80 [GPIO_LEVELDETECT1] = 0x44, 81 [GPIO_LEVELDETECT1] = 0x44,
81 [GPIO_RISINGDETECT] = 0x48, 82 [GPIO_RISINGDETECT] = 0x48,
82 [GPIO_FALLINGDETECT] = 0x4c, 83 [GPIO_FALLINGDETECT] = 0x4c,
83 [GPIO_CLEARDATAOUT] = 0x90, 84 [GPIO_CLEARDATAOUT] = 0x90,
84 [GPIO_SETDATAOUT] = 0x94, 85 [GPIO_SETDATAOUT] = 0x94,
85 }, 86 },
86 [TI_GPIO_OMAP4] = { 87 [TI_GPIO_OMAP4] = {
87 [GPIO_IRQSTATUS1] = 0x2c, 88 [GPIO_IRQSTATUS1] = 0x2c,
88 [GPIO_IRQENABLE1_SET] = 0x34, 89 [GPIO_IRQENABLE1_SET] = 0x34,
89 [GPIO_IRQENABLE1_CLR] = 0x38, 90 [GPIO_IRQENABLE1_CLR] = 0x38,
90 [GPIO_OE] = 0x134, 91 [GPIO_OE] = 0x134,
91 [GPIO_DATAIN] = 0x138, 92 [GPIO_DATAIN] = 0x138,
92 [GPIO_DATAOUT] = 0x13c, 93 [GPIO_DATAOUT] = 0x13c,
93 [GPIO_LEVELDETECT0] = 0x140, 94 [GPIO_LEVELDETECT0] = 0x140,
94 [GPIO_LEVELDETECT1] = 0x144, 95 [GPIO_LEVELDETECT1] = 0x144,
95 [GPIO_RISINGDETECT] = 0x148, 96 [GPIO_RISINGDETECT] = 0x148,
96 [GPIO_FALLINGDETECT] = 0x14c, 97 [GPIO_FALLINGDETECT] = 0x14c,
97 [GPIO_CLEARDATAOUT] = 0x190, 98 [GPIO_CLEARDATAOUT] = 0x190,
98 [GPIO_SETDATAOUT] = 0x194, 99 [GPIO_SETDATAOUT] = 0x194,
99 }, 100 },
100}; 101};
101 102
102static const struct device_compatible_entry compat_data[] = { 103static const struct device_compatible_entry compat_data[] = {
103 { .compat = "ti,omap3-gpio", .value = TI_GPIO_OMAP3 }, 104 { .compat = "ti,omap3-gpio", .value = TI_GPIO_OMAP3 },
104 { .compat = "ti,omap4-gpio", .value = TI_GPIO_OMAP4 }, 105 { .compat = "ti,omap4-gpio", .value = TI_GPIO_OMAP4 },
105 DEVICE_COMPAT_EOL 106 DEVICE_COMPAT_EOL
106}; 107};
107 108
108struct ti_gpio_intr { 109struct ti_gpio_intr {
109 u_int intr_pin; 110 u_int intr_pin;
110 int (*intr_func)(void *); 111 int (*intr_func)(void *);
111 void *intr_arg; 112 void *intr_arg;
112 bool intr_mpsafe; 113 bool intr_mpsafe;
113}; 114};
114 115
115struct ti_gpio_softc { 116struct ti_gpio_softc {
116 device_t sc_dev; 117 device_t sc_dev;
117 bus_space_tag_t sc_bst; 118 bus_space_tag_t sc_bst;
118 bus_space_handle_t sc_bsh; 119 bus_space_handle_t sc_bsh;
119 kmutex_t sc_lock; 120 kmutex_t sc_lock;
120 enum ti_gpio_type sc_type; 121 enum ti_gpio_type sc_type;
121 const char *sc_modname; 122 const char *sc_modname;
122 void *sc_ih; 123 void *sc_ih;
123 124
124 struct gpio_chipset_tag sc_gp; 125 struct gpio_chipset_tag sc_gp;
125 gpio_pin_t sc_pins[TI_GPIO_NPINS]; 126 gpio_pin_t sc_pins[TI_GPIO_NPINS];
126 bool sc_pinout[TI_GPIO_NPINS]; 127 bool sc_pinout[TI_GPIO_NPINS];
127 struct ti_gpio_intr sc_intr[TI_GPIO_NPINS]; 128 struct ti_gpio_intr sc_intr[TI_GPIO_NPINS];
128 device_t sc_gpiodev; 129 device_t sc_gpiodev;
129}; 130};
130 131
131struct ti_gpio_pin { 132struct ti_gpio_pin {
132 struct ti_gpio_softc *pin_sc; 133 struct ti_gpio_softc *pin_sc;
133 u_int pin_nr; 134 u_int pin_nr;
134 int pin_flags; 135 int pin_flags;
135 bool pin_actlo; 136 bool pin_actlo;
136}; 137};
137 138
138#define RD4(sc, reg) \ 139#define RD4(sc, reg) \
139 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)]) 140 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)])
140#define WR4(sc, reg, val) \ 141#define WR4(sc, reg, val) \
141 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)], (val)) 142 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)], (val))
142 143
143static int ti_gpio_match(device_t, cfdata_t, void *); 144static int ti_gpio_match(device_t, cfdata_t, void *);
144static void ti_gpio_attach(device_t, device_t, void *); 145static void ti_gpio_attach(device_t, device_t, void *);
145 146
146CFATTACH_DECL_NEW(ti_gpio, sizeof(struct ti_gpio_softc), 147CFATTACH_DECL_NEW(ti_gpio, sizeof(struct ti_gpio_softc),
147 ti_gpio_match, ti_gpio_attach, NULL, NULL); 148 ti_gpio_match, ti_gpio_attach, NULL, NULL);
148 149
149static int 150static int
150ti_gpio_ctl(struct ti_gpio_softc *sc, u_int pin, int flags) 151ti_gpio_ctl(struct ti_gpio_softc *sc, u_int pin, int flags)
151{ 152{
152 uint32_t oe; 153 uint32_t oe;
153 154
154 KASSERT(mutex_owned(&sc->sc_lock)); 155 KASSERT(mutex_owned(&sc->sc_lock));
155 156
156 oe = RD4(sc, GPIO_OE); 157 oe = RD4(sc, GPIO_OE);
157 if (flags & GPIO_PIN_INPUT) 158 if (flags & GPIO_PIN_INPUT)
158 oe |= __BIT(pin); 159 oe |= __BIT(pin);
159 else if (flags & GPIO_PIN_OUTPUT) 160 else if (flags & GPIO_PIN_OUTPUT)
160 oe &= ~__BIT(pin); 161 oe &= ~__BIT(pin);
161 WR4(sc, GPIO_OE, oe); 162 WR4(sc, GPIO_OE, oe);
162 163
163 sc->sc_pinout[pin] = (flags & GPIO_PIN_OUTPUT) != 0; 164 sc->sc_pinout[pin] = (flags & GPIO_PIN_OUTPUT) != 0;
164 165
165 return 0; 166 return 0;
166} 167}
167 168
168static void * 169static void *
169ti_gpio_acquire(device_t dev, const void *data, size_t len, int flags) 170ti_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
170{ 171{
171 struct ti_gpio_softc * const sc = device_private(dev); 172 struct ti_gpio_softc * const sc = device_private(dev);
172 struct ti_gpio_pin *gpin; 173 struct ti_gpio_pin *gpin;
173 const u_int *gpio = data; 174 const u_int *gpio = data;
174 int error; 175 int error;
175 176
176 if (len != 12) 177 if (len != 12)
177 return NULL; 178 return NULL;
178 179
179 const uint8_t pin = be32toh(gpio[1]) & 0xff; 180 const uint8_t pin = be32toh(gpio[1]) & 0xff;
180 const bool actlo = be32toh(gpio[2]) & 1; 181 const bool actlo = be32toh(gpio[2]) & 1;
181 182
182 if (pin >= __arraycount(sc->sc_pins)) 183 if (pin >= __arraycount(sc->sc_pins))
183 return NULL; 184 return NULL;
184 185
185 mutex_enter(&sc->sc_lock); 186 mutex_enter(&sc->sc_lock);
186 error = ti_gpio_ctl(sc, pin, flags); 187 error = ti_gpio_ctl(sc, pin, flags);
187 mutex_exit(&sc->sc_lock); 188 mutex_exit(&sc->sc_lock);
188 189
189 if (error != 0) 190 if (error != 0)
190 return NULL; 191 return NULL;
191 192
192 gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP); 193 gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
193 gpin->pin_sc = sc; 194 gpin->pin_sc = sc;
194 gpin->pin_nr = pin; 195 gpin->pin_nr = pin;
195 gpin->pin_flags = flags; 196 gpin->pin_flags = flags;
196 gpin->pin_actlo = actlo; 197 gpin->pin_actlo = actlo;
197 198
198 return gpin; 199 return gpin;
199} 200}
200 201
201static void 202static void
202ti_gpio_release(device_t dev, void *priv) 203ti_gpio_release(device_t dev, void *priv)
203{ 204{
204 struct ti_gpio_softc * const sc = device_private(dev); 205 struct ti_gpio_softc * const sc = device_private(dev);
205 struct ti_gpio_pin *pin = priv; 206 struct ti_gpio_pin *pin = priv;
206 207
207 mutex_enter(&sc->sc_lock); 208 mutex_enter(&sc->sc_lock);
208 ti_gpio_ctl(pin->pin_sc, pin->pin_nr, GPIO_PIN_INPUT); 209 ti_gpio_ctl(pin->pin_sc, pin->pin_nr, GPIO_PIN_INPUT);
209 mutex_exit(&sc->sc_lock); 210 mutex_exit(&sc->sc_lock);
210 211
211 kmem_free(pin, sizeof(*pin)); 212 kmem_free(pin, sizeof(*pin));
212} 213}
213 214
214static int 215static int
215ti_gpio_read(device_t dev, void *priv, bool raw) 216ti_gpio_read(device_t dev, void *priv, bool raw)
216{ 217{
217 struct ti_gpio_softc * const sc = device_private(dev); 218 struct ti_gpio_softc * const sc = device_private(dev);
218 struct ti_gpio_pin *pin = priv; 219 struct ti_gpio_pin *pin = priv;
219 uint32_t data; 220 uint32_t data;
220 int val; 221 int val;
221 222
222 KASSERT(sc == pin->pin_sc); 223 KASSERT(sc == pin->pin_sc);
223 224
224 const uint32_t data_mask = __BIT(pin->pin_nr); 225 const uint32_t data_mask = __BIT(pin->pin_nr);
225 226
226 /* No lock required for reads */ 227 /* No lock required for reads */
227 if (sc->sc_pinout[pin->pin_nr]) 228 if (sc->sc_pinout[pin->pin_nr])
228 data = RD4(sc, GPIO_DATAOUT); 229 data = RD4(sc, GPIO_DATAOUT);
229 else 230 else
230 data = RD4(sc, GPIO_DATAIN); 231 data = RD4(sc, GPIO_DATAIN);
231 val = __SHIFTOUT(data, data_mask); 232 val = __SHIFTOUT(data, data_mask);
232 if (!raw && pin->pin_actlo) 233 if (!raw && pin->pin_actlo)
233 val = !val; 234 val = !val;
234 235
235 return val; 236 return val;
236} 237}
237 238
238static void 239static void
239ti_gpio_write(device_t dev, void *priv, int val, bool raw) 240ti_gpio_write(device_t dev, void *priv, int val, bool raw)
240{ 241{
241 struct ti_gpio_softc * const sc = device_private(dev); 242 struct ti_gpio_softc * const sc = device_private(dev);
242 struct ti_gpio_pin *pin = priv; 243 struct ti_gpio_pin *pin = priv;
243 244
244 KASSERT(sc == pin->pin_sc); 245 KASSERT(sc == pin->pin_sc);
245 246
246 const uint32_t data_mask = __BIT(pin->pin_nr); 247 const uint32_t data_mask = __BIT(pin->pin_nr);
247 248
248 if (!raw && pin->pin_actlo) 249 if (!raw && pin->pin_actlo)
249 val = !val; 250 val = !val;
250 251
251 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT; 252 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT;
252 253
253 WR4(sc, data_reg, data_mask); 254 WR4(sc, data_reg, data_mask);
254} 255}
255 256
256static struct fdtbus_gpio_controller_func ti_gpio_funcs = { 257static struct fdtbus_gpio_controller_func ti_gpio_funcs = {
257 .acquire = ti_gpio_acquire, 258 .acquire = ti_gpio_acquire,
258 .release = ti_gpio_release, 259 .release = ti_gpio_release,
259 .read = ti_gpio_read, 260 .read = ti_gpio_read,
260 .write = ti_gpio_write, 261 .write = ti_gpio_write,
261}; 262};
262 263
263static void 264static void
264ti_gpio_intr_disestablish(device_t dev, void *ih) 265ti_gpio_intr_disestablish(device_t dev, void *ih)
265{ 266{
266 struct ti_gpio_softc * const sc = device_private(dev); 267 struct ti_gpio_softc * const sc = device_private(dev);
267 struct ti_gpio_intr *intr = ih; 268 struct ti_gpio_intr *intr = ih;
268 const u_int pin = intr->intr_pin; 269 const u_int pin = intr->intr_pin;
269 const uint32_t pin_mask = __BIT(pin); 270 const uint32_t pin_mask = __BIT(pin);
270 uint32_t val; 271 uint32_t val;
271 272
272 /* Disable interrupts */ 273 /* Disable interrupts */
273 if (sc->sc_type == TI_GPIO_OMAP3) { 274 if (sc->sc_type == TI_GPIO_OMAP3) {
274 val = RD4(sc, GPIO_IRQENABLE1); 275 val = RD4(sc, GPIO_IRQENABLE1);
275 WR4(sc, GPIO_IRQENABLE1, val & ~pin_mask); 276 WR4(sc, GPIO_IRQENABLE1, val & ~pin_mask);
276 } else { 277 } else {
277 WR4(sc, GPIO_IRQENABLE1_CLR, pin_mask); 278 WR4(sc, GPIO_IRQENABLE1_CLR, pin_mask);
278 } 279 }
279 280
280 intr->intr_func = NULL; 281 intr->intr_func = NULL;
281 intr->intr_arg = NULL; 282 intr->intr_arg = NULL;
282} 283}
283 284
284static void * 285static void *
285ti_gpio_intr_establish(device_t dev, u_int *specifier, int ipl, int flags, 286ti_gpio_intr_establish(device_t dev, u_int *specifier, int ipl, int flags,
286 int (*func)(void *), void *arg, const char *xname) 287 int (*func)(void *), void *arg, const char *xname)
287{ 288{
288 struct ti_gpio_softc * const sc = device_private(dev); 289 struct ti_gpio_softc * const sc = device_private(dev);
289 uint32_t val; 290 uint32_t val;
290 291
291 /* 1st cell is the pin */ 292 /* 1st cell is the pin */
292 /* 2nd cell is flags */ 293 /* 2nd cell is flags */
293 const u_int pin = be32toh(specifier[0]); 294 const u_int pin = be32toh(specifier[0]);
294 const u_int type = be32toh(specifier[2]) & 0xf; 295 const u_int type = be32toh(specifier[2]) & 0xf;
295 296
296 if (ipl != IPL_VM || pin >= __arraycount(sc->sc_pins)) 297 if (ipl != IPL_VM || pin >= __arraycount(sc->sc_pins))
297 return NULL; 298 return NULL;
298 299
299 /* 300 /*
300 * Enabling both high and low level triggers will cause the GPIO 301 * Enabling both high and low level triggers will cause the GPIO
301 * controller to always assert the interrupt. 302 * controller to always assert the interrupt.
302 */ 303 */
303 if ((type & (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) == 304 if ((type & (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) ==
304 (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) 305 (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL))
305 return NULL; 306 return NULL;
306 307
307 if (sc->sc_intr[pin].intr_func != NULL) 308 if (sc->sc_intr[pin].intr_func != NULL)
308 return NULL; 309 return NULL;
309 310
310 /* Set pin as input */ 311 /* Set pin as input */
311 if (ti_gpio_ctl(sc, pin, GPIO_PIN_INPUT) != 0) 312 if (ti_gpio_ctl(sc, pin, GPIO_PIN_INPUT) != 0)
312 return NULL; 313 return NULL;
313 314
314 sc->sc_intr[pin].intr_pin = pin; 315 sc->sc_intr[pin].intr_pin = pin;
315 sc->sc_intr[pin].intr_func = func; 316 sc->sc_intr[pin].intr_func = func;
316 sc->sc_intr[pin].intr_arg = arg; 317 sc->sc_intr[pin].intr_arg = arg;
317 sc->sc_intr[pin].intr_mpsafe = (flags & FDT_INTR_MPSAFE) != 0; 318 sc->sc_intr[pin].intr_mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
318 319
319 const uint32_t pin_mask = __BIT(pin); 320 const uint32_t pin_mask = __BIT(pin);
320 321
321 /* Configure triggers */ 322 /* Configure triggers */
322 val = RD4(sc, GPIO_LEVELDETECT0); 323 val = RD4(sc, GPIO_LEVELDETECT0);
323 if ((type & FDT_INTR_TYPE_LOW_LEVEL) != 0) 324 if ((type & FDT_INTR_TYPE_LOW_LEVEL) != 0)
324 val |= pin_mask; 325 val |= pin_mask;
325 else 326 else
326 val &= ~pin_mask; 327 val &= ~pin_mask;
327 WR4(sc, GPIO_LEVELDETECT0, val); 328 WR4(sc, GPIO_LEVELDETECT0, val);
328 329
329 val = RD4(sc, GPIO_LEVELDETECT1); 330 val = RD4(sc, GPIO_LEVELDETECT1);
330 if ((type & FDT_INTR_TYPE_HIGH_LEVEL) != 0) 331 if ((type & FDT_INTR_TYPE_HIGH_LEVEL) != 0)
331 val |= pin_mask; 332 val |= pin_mask;
332 else 333 else
333 val &= ~pin_mask; 334 val &= ~pin_mask;
334 WR4(sc, GPIO_LEVELDETECT1, val); 335 WR4(sc, GPIO_LEVELDETECT1, val);
335 336
336 val = RD4(sc, GPIO_RISINGDETECT); 337 val = RD4(sc, GPIO_RISINGDETECT);
337 if ((type & FDT_INTR_TYPE_POS_EDGE) != 0) 338 if ((type & FDT_INTR_TYPE_POS_EDGE) != 0)
338 val |= pin_mask; 339 val |= pin_mask;
339 else 340 else
340 val &= ~pin_mask; 341 val &= ~pin_mask;
341 WR4(sc, GPIO_RISINGDETECT, val); 342 WR4(sc, GPIO_RISINGDETECT, val);
342 343
343 val = RD4(sc, GPIO_FALLINGDETECT); 344 val = RD4(sc, GPIO_FALLINGDETECT);
344 if ((type & FDT_INTR_TYPE_NEG_EDGE) != 0) 345 if ((type & FDT_INTR_TYPE_NEG_EDGE) != 0)
345 val |= pin_mask; 346 val |= pin_mask;
346 else 347 else
347 val &= ~pin_mask; 348 val &= ~pin_mask;
348 WR4(sc, GPIO_FALLINGDETECT, val); 349 WR4(sc, GPIO_FALLINGDETECT, val);
349 350
350 /* Enable interrupts */ 351 /* Enable interrupts */
351 if (sc->sc_type == TI_GPIO_OMAP3) { 352 if (sc->sc_type == TI_GPIO_OMAP3) {
352 val = RD4(sc, GPIO_IRQENABLE1); 353 val = RD4(sc, GPIO_IRQENABLE1);
353 WR4(sc, GPIO_IRQENABLE1, val | pin_mask); 354 WR4(sc, GPIO_IRQENABLE1, val | pin_mask);
354 } else { 355 } else {
355 WR4(sc, GPIO_IRQENABLE1_SET, pin_mask); 356 WR4(sc, GPIO_IRQENABLE1_SET, pin_mask);
356 } 357 }
357 358
358 return &sc->sc_intr[pin]; 359 return &sc->sc_intr[pin];
359} 360}
360 361
361static bool 362static bool
362ti_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) 363ti_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
363{ 364{
364 struct ti_gpio_softc * const sc = device_private(dev); 365 struct ti_gpio_softc * const sc = device_private(dev);
365 366
366 /* 1st cell is the pin */ 367 /* 1st cell is the pin */
367 /* 2nd cell is flags */ 368 /* 2nd cell is flags */
368 const u_int pin = be32toh(specifier[0]); 369 const u_int pin = be32toh(specifier[0]);
369 370
370 if (pin >= __arraycount(sc->sc_pins)) 371 if (pin >= __arraycount(sc->sc_pins))
371 return false; 372 return false;
372 373
373 snprintf(buf, buflen, "%s pin %d", sc->sc_modname, pin); 374 snprintf(buf, buflen, "%s pin %d", sc->sc_modname, pin);
374 return true; 375 return true;
375} 376}
376 377
377static struct fdtbus_interrupt_controller_func ti_gpio_intrfuncs = { 378static struct fdtbus_interrupt_controller_func ti_gpio_intrfuncs = {
378 .establish = ti_gpio_intr_establish, 379 .establish = ti_gpio_intr_establish,
379 .disestablish = ti_gpio_intr_disestablish, 380 .disestablish = ti_gpio_intr_disestablish,
380 .intrstr = ti_gpio_intrstr, 381 .intrstr = ti_gpio_intrstr,
381}; 382};
382 383
383static int 384static int
384ti_gpio_pin_read(void *priv, int pin) 385ti_gpio_pin_read(void *priv, int pin)
385{ 386{
386 struct ti_gpio_softc * const sc = priv; 387 struct ti_gpio_softc * const sc = priv;
387 uint32_t data; 388 uint32_t data;
388 int val; 389 int val;
389 390
390 KASSERT(pin < __arraycount(sc->sc_pins)); 391 KASSERT(pin < __arraycount(sc->sc_pins));
391 392
392 const uint32_t data_mask = __BIT(pin); 393 const uint32_t data_mask = __BIT(pin);
393 394
394 data = RD4(sc, GPIO_DATAIN); 395 data = RD4(sc, GPIO_DATAIN);
395 val = __SHIFTOUT(data, data_mask); 396 val = __SHIFTOUT(data, data_mask);
396 397
397 return val; 398 return val;
398} 399}
399 400
400static void 401static void
401ti_gpio_pin_write(void *priv, int pin, int val) 402ti_gpio_pin_write(void *priv, int pin, int val)
402{ 403{
403 struct ti_gpio_softc * const sc = priv; 404 struct ti_gpio_softc * const sc = priv;
404 405
405 KASSERT(pin < __arraycount(sc->sc_pins)); 406 KASSERT(pin < __arraycount(sc->sc_pins));
406 407
407 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT; 408 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT;
408 const uint32_t data_mask = __BIT(pin); 409 const uint32_t data_mask = __BIT(pin);
409 410
410 WR4(sc, data_reg, data_mask); 411 WR4(sc, data_reg, data_mask);
411} 412}
412 413
413static void 414static void
414ti_gpio_pin_ctl(void *priv, int pin, int flags) 415ti_gpio_pin_ctl(void *priv, int pin, int flags)
415{ 416{
416 struct ti_gpio_softc * const sc = priv; 417 struct ti_gpio_softc * const sc = priv;
417 418
418 KASSERT(pin < __arraycount(sc->sc_pins)); 419 KASSERT(pin < __arraycount(sc->sc_pins));
419 420
420 mutex_enter(&sc->sc_lock); 421 mutex_enter(&sc->sc_lock);
421 ti_gpio_ctl(sc, pin, flags); 422 ti_gpio_ctl(sc, pin, flags);
422 mutex_exit(&sc->sc_lock); 423 mutex_exit(&sc->sc_lock);
423} 424}
424 425
425static void 426static void
426ti_gpio_attach_ports(struct ti_gpio_softc *sc) 427ti_gpio_attach_ports(struct ti_gpio_softc *sc)
427{ 428{
428 struct gpio_chipset_tag *gp = &sc->sc_gp; 429 struct gpio_chipset_tag *gp = &sc->sc_gp;
429 struct gpiobus_attach_args gba; 430 struct gpiobus_attach_args gba;
430 u_int pin; 431 u_int pin;
431 432
432 gp->gp_cookie = sc; 433 gp->gp_cookie = sc;
433 gp->gp_pin_read = ti_gpio_pin_read; 434 gp->gp_pin_read = ti_gpio_pin_read;
434 gp->gp_pin_write = ti_gpio_pin_write; 435 gp->gp_pin_write = ti_gpio_pin_write;
435 gp->gp_pin_ctl = ti_gpio_pin_ctl; 436 gp->gp_pin_ctl = ti_gpio_pin_ctl;
436 437
437 for (pin = 0; pin < __arraycount(sc->sc_pins); pin++) { 438 for (pin = 0; pin < __arraycount(sc->sc_pins); pin++) {
438 sc->sc_pins[pin].pin_num = pin; 439 sc->sc_pins[pin].pin_num = pin;
439 sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 440 sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
440 sc->sc_pins[pin].pin_state = ti_gpio_pin_read(sc, pin); 441 sc->sc_pins[pin].pin_state = ti_gpio_pin_read(sc, pin);
441 } 442 }
442 443
443 memset(&gba, 0, sizeof(gba)); 444 memset(&gba, 0, sizeof(gba));
444 gba.gba_gc = gp; 445 gba.gba_gc = gp;
445 gba.gba_pins = sc->sc_pins; 446 gba.gba_pins = sc->sc_pins;
446 gba.gba_npins = __arraycount(sc->sc_pins); 447 gba.gba_npins = __arraycount(sc->sc_pins);
447 sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL); 448 sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL);
448} 449}
449 450
450static int 451static int
451ti_gpio_intr(void *priv) 452ti_gpio_intr(void *priv)
452{ 453{
453 struct ti_gpio_softc * const sc = priv; 454 struct ti_gpio_softc * const sc = priv;
454 uint32_t status; 455 uint32_t status;
455 u_int bit; 456 u_int bit;
456 int rv = 0; 457 int rv = 0;
457 458
458 status = RD4(sc, GPIO_IRQSTATUS1); 459 status = RD4(sc, GPIO_IRQSTATUS1);
459 WR4(sc, GPIO_IRQSTATUS1, status); 460 WR4(sc, GPIO_IRQSTATUS1, status);
460 461
461 while ((bit = ffs32(status)) != 0) { 462 while ((bit = ffs32(status)) != 0) {
462 const u_int pin = bit - 1; 463 const u_int pin = bit - 1;
463 const uint32_t pin_mask = __BIT(pin); 464 const uint32_t pin_mask = __BIT(pin);
464 struct ti_gpio_intr *intr = &sc->sc_intr[pin]; 465 struct ti_gpio_intr *intr = &sc->sc_intr[pin];
465 status &= ~pin_mask; 466 status &= ~pin_mask;
466 if (intr->intr_func == NULL) 467 if (intr->intr_func == NULL)
467 continue; 468 continue;
468 if (!intr->intr_mpsafe) 469 if (!intr->intr_mpsafe)
469 KERNEL_LOCK(1, curlwp); 470 KERNEL_LOCK(1, curlwp);
470 rv |= intr->intr_func(intr->intr_arg); 471 rv |= intr->intr_func(intr->intr_arg);
471 if (!intr->intr_mpsafe) 472 if (!intr->intr_mpsafe)
472 KERNEL_UNLOCK_ONE(curlwp); 473 KERNEL_UNLOCK_ONE(curlwp);
473 } 474 }
474 475
475 return rv; 476 return rv;
476} 477}
477 478
478static int 479static int
479ti_gpio_match(device_t parent, cfdata_t cf, void *aux) 480ti_gpio_match(device_t parent, cfdata_t cf, void *aux)
480{ 481{
481 struct fdt_attach_args * const faa = aux; 482 struct fdt_attach_args * const faa = aux;
482 483
483 return of_compatible_match(faa->faa_phandle, compat_data); 484 return of_compatible_match(faa->faa_phandle, compat_data);
484} 485}
485 486
486static void 487static void
487ti_gpio_attach(device_t parent, device_t self, void *aux) 488ti_gpio_attach(device_t parent, device_t self, void *aux)
488{ 489{
489 struct ti_gpio_softc * const sc = device_private(self); 490 struct ti_gpio_softc * const sc = device_private(self);
490 struct fdt_attach_args * const faa = aux; 491 struct fdt_attach_args * const faa = aux;
491 const int phandle = faa->faa_phandle; 492 const int phandle = faa->faa_phandle;
492 char intrstr[128]; 493 char intrstr[128];
493 bus_addr_t addr; 494 bus_addr_t addr;
494 bus_size_t size; 495 bus_size_t size;
495 496
496 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 497 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
497 aprint_error(": couldn't get registers\n"); 498 aprint_error(": couldn't get registers\n");
498 return; 499 return;
499 } 500 }
500 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 501 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
501 aprint_error(": couldn't decode interrupt\n"); 502 aprint_error(": couldn't decode interrupt\n");
502 return; 503 return;
503 } 504 }
504 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 505 if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
505 aprint_error(": couldn't enable module\n"); 506 aprint_error(": couldn't enable module\n");
506 return; 507 return;
507 } 508 }
508 509
509 sc->sc_dev = self; 510 sc->sc_dev = self;
510 sc->sc_bst = faa->faa_bst; 511 sc->sc_bst = faa->faa_bst;
511 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 512 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
512 aprint_error(": couldn't map registers\n"); 513 aprint_error(": couldn't map registers\n");
513 return; 514 return;
514 } 515 }
515 sc->sc_type = of_compatible_lookup(phandle, compat_data)->value; 516 sc->sc_type = of_compatible_lookup(phandle, compat_data)->value;
516 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 517 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
517 518
518 sc->sc_modname = fdtbus_get_string(phandle, "ti,hwmods"); 519 sc->sc_modname = fdtbus_get_string(phandle, "ti,hwmods");
519 if (sc->sc_modname == NULL) 520 if (sc->sc_modname == NULL)
520 sc->sc_modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods"); 521 sc->sc_modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
521 if (sc->sc_modname == NULL) 522 if (sc->sc_modname == NULL)
522 sc->sc_modname = kmem_asprintf("gpio@%" PRIxBUSADDR, addr); 523 sc->sc_modname = kmem_asprintf("gpio@%" PRIxBUSADDR, addr);
523 524
524 aprint_naive("\n"); 525 aprint_naive("\n");
525 aprint_normal(": GPIO (%s)\n", sc->sc_modname); 526 aprint_normal(": GPIO (%s)\n", sc->sc_modname);
526 527
527 fdtbus_register_gpio_controller(self, phandle, &ti_gpio_funcs); 528 fdtbus_register_gpio_controller(self, phandle, &ti_gpio_funcs);
528 529
529 ti_gpio_attach_ports(sc); 530 ti_gpio_attach_ports(sc);
530 531
531 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, 532 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM,
532 FDT_INTR_MPSAFE, ti_gpio_intr, sc, device_xname(self)); 533 FDT_INTR_MPSAFE, ti_gpio_intr, sc, device_xname(self));
533 if (sc->sc_ih == NULL) { 534 if (sc->sc_ih == NULL) {
534 aprint_error_dev(self, "failed to establish interrupt on %s\n", 535 aprint_error_dev(self, "failed to establish interrupt on %s\n",
535 intrstr); 536 intrstr);
536 return; 537 return;
537 } 538 }
538 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 539 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
539 fdtbus_register_interrupt_controller(self, phandle, &ti_gpio_intrfuncs); 540 fdtbus_register_interrupt_controller(self, phandle, &ti_gpio_intrfuncs);
540} 541}