Sat Oct 17 14:46:01 2015 UTC ()
awin_cpu_clk(): Fix reading of CPU_CLK_SRC_CEL bits: doing a shiftin followed
by a shiftout ends up reading bits(0,1) instead of AWIN_CPU_CLK_SRC_SEL.
It happens that these bits (AWIN_AXI_CLK_DIV_RATIO) are 2 (divide by 3) at boot
(at last on cubieboard2 and olimex lime2), which matches
AWIN_CPU_CLK_SRC_SEL_PLL1, so this has gone  unnoticed.


(bouyer)
diff -r1.35 -r1.36 src/sys/arch/arm/allwinner/awin_board.c

cvs diff -r1.35 -r1.36 src/sys/arch/arm/allwinner/Attic/awin_board.c (switch to unified diff)

--- src/sys/arch/arm/allwinner/Attic/awin_board.c 2015/04/20 01:33:22 1.35
+++ src/sys/arch/arm/allwinner/Attic/awin_board.c 2015/10/17 14:46:01 1.36
@@ -1,629 +1,628 @@ @@ -1,629 +1,628 @@
1/* $NetBSD: awin_board.c,v 1.35 2015/04/20 01:33:22 matt Exp $ */ 1/* $NetBSD: awin_board.c,v 1.36 2015/10/17 14:46:01 bouyer Exp $ */
2/*- 2/*-
3 * Copyright (c) 2012 The NetBSD Foundation, Inc. 3 * Copyright (c) 2012 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to The NetBSD Foundation 6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas of 3am Software Foundry. 7 * by Matt Thomas of 3am Software Foundry.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE. 28 * POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31#include "opt_allwinner.h" 31#include "opt_allwinner.h"
32#include "opt_arm_debug.h" 32#include "opt_arm_debug.h"
33#include "opt_multiprocessor.h" 33#include "opt_multiprocessor.h"
34 34
35#define _ARM32_BUS_DMA_PRIVATE 35#define _ARM32_BUS_DMA_PRIVATE
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38 38
39__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.35 2015/04/20 01:33:22 matt Exp $"); 39__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.36 2015/10/17 14:46:01 bouyer Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/bus.h> 42#include <sys/bus.h>
43#include <sys/cpu.h> 43#include <sys/cpu.h>
44#include <sys/device.h> 44#include <sys/device.h>
45 45
46#include <prop/proplib.h> 46#include <prop/proplib.h>
47 47
48#include <net/if.h> 48#include <net/if.h>
49#include <net/if_ether.h> 49#include <net/if_ether.h>
50 50
51#include <arm/locore.h> 51#include <arm/locore.h>
52 52
53#include <arm/mainbus/mainbus.h> 53#include <arm/mainbus/mainbus.h>
54 54
55#include <arm/allwinner/awin_reg.h> 55#include <arm/allwinner/awin_reg.h>
56#include <arm/allwinner/awin_var.h> 56#include <arm/allwinner/awin_var.h>
57 57
58#include <arm/cortex/gtmr_var.h> 58#include <arm/cortex/gtmr_var.h>
59 59
60bus_space_handle_t awin_core_bsh; 60bus_space_handle_t awin_core_bsh;
61#if defined(ALLWINNER_A80) 61#if defined(ALLWINNER_A80)
62bus_space_handle_t awin_core2_bsh; 62bus_space_handle_t awin_core2_bsh;
63bus_space_handle_t awin_rcpus_bsh; 63bus_space_handle_t awin_rcpus_bsh;
64#endif 64#endif
65 65
66struct arm32_bus_dma_tag awin_dma_tag = { 66struct arm32_bus_dma_tag awin_dma_tag = {
67 _BUS_DMAMAP_FUNCS, 67 _BUS_DMAMAP_FUNCS,
68 _BUS_DMAMEM_FUNCS, 68 _BUS_DMAMEM_FUNCS,
69 _BUS_DMATAG_FUNCS, 69 _BUS_DMATAG_FUNCS,
70}; 70};
71 71
72struct arm32_dma_range awin_coherent_dma_ranges[] = { 72struct arm32_dma_range awin_coherent_dma_ranges[] = {
73 [0] = { 73 [0] = {
74 .dr_sysbase = AWIN_SDRAM_PBASE, 74 .dr_sysbase = AWIN_SDRAM_PBASE,
75 .dr_busbase = AWIN_SDRAM_PBASE, 75 .dr_busbase = AWIN_SDRAM_PBASE,
76 .dr_flags = _BUS_DMAMAP_COHERENT, 76 .dr_flags = _BUS_DMAMAP_COHERENT,
77 }, 77 },
78}; 78};
79 79
80 80
81struct arm32_bus_dma_tag awin_coherent_dma_tag = { 81struct arm32_bus_dma_tag awin_coherent_dma_tag = {
82 ._ranges = awin_coherent_dma_ranges, 82 ._ranges = awin_coherent_dma_ranges,
83 ._nranges = __arraycount(awin_coherent_dma_ranges), 83 ._nranges = __arraycount(awin_coherent_dma_ranges),
84 _BUS_DMAMAP_FUNCS, 84 _BUS_DMAMAP_FUNCS,
85 _BUS_DMAMEM_FUNCS, 85 _BUS_DMAMEM_FUNCS,
86 _BUS_DMATAG_FUNCS, 86 _BUS_DMATAG_FUNCS,
87}; 87};
88 88
89#ifdef AWIN_CONSOLE_EARLY 89#ifdef AWIN_CONSOLE_EARLY
90#include <dev/ic/ns16550reg.h> 90#include <dev/ic/ns16550reg.h>
91#include <dev/ic/comreg.h> 91#include <dev/ic/comreg.h>
92#include <dev/cons.h> 92#include <dev/cons.h>
93 93
94static volatile uint32_t *uart_base; 94static volatile uint32_t *uart_base;
95 95
96static int 96static int
97awin_cngetc(dev_t dv) 97awin_cngetc(dev_t dv)
98{ 98{
99 if ((le32toh(uart_base[com_lsr]) & LSR_RXRDY) == 0) 99 if ((le32toh(uart_base[com_lsr]) & LSR_RXRDY) == 0)
100 return -1; 100 return -1;
101 101
102 return le32toh(uart_base[com_data]) & 0xff; 102 return le32toh(uart_base[com_data]) & 0xff;
103} 103}
104 104
105static void 105static void
106awin_cnputc(dev_t dv, int c) 106awin_cnputc(dev_t dv, int c)
107{ 107{
108 int timo = 150000; 108 int timo = 150000;
109 109
110 while ((le32toh(uart_base[com_lsr]) & LSR_TXRDY) == 0 && --timo > 0) 110 while ((le32toh(uart_base[com_lsr]) & LSR_TXRDY) == 0 && --timo > 0)
111 ; 111 ;
112 112
113 uart_base[com_data] = htole32(c & 0xff); 113 uart_base[com_data] = htole32(c & 0xff);
114 114
115 timo = 150000; 115 timo = 150000;
116 while ((le32toh(uart_base[com_lsr]) & LSR_TSRE) == 0 && --timo > 0) 116 while ((le32toh(uart_base[com_lsr]) & LSR_TSRE) == 0 && --timo > 0)
117 ; 117 ;
118} 118}
119 119
120static struct consdev awin_earlycons = { 120static struct consdev awin_earlycons = {
121 .cn_putc = awin_cnputc, 121 .cn_putc = awin_cnputc,
122 .cn_getc = awin_cngetc, 122 .cn_getc = awin_cngetc,
123 .cn_pollc = nullcnpollc, 123 .cn_pollc = nullcnpollc,
124}; 124};
125#endif /* AWIN_CONSOLE_EARLY */ 125#endif /* AWIN_CONSOLE_EARLY */
126 126
127static void 127static void
128awin_cpu_clk(void) 128awin_cpu_clk(void)
129{ 129{
130 struct cpu_info * const ci = curcpu(); 130 struct cpu_info * const ci = curcpu();
131 bus_space_tag_t bst = &armv7_generic_bs_tag; 131 bus_space_tag_t bst = &armv7_generic_bs_tag;
132 132
133#if defined(ALLWINNER_A80) 133#if defined(ALLWINNER_A80)
134 const uint32_t c0cpux = bus_space_read_4(bst, awin_core_bsh, 134 const uint32_t c0cpux = bus_space_read_4(bst, awin_core_bsh,
135 AWIN_A80_CCU_OFFSET + AWIN_A80_CCU_PLL_C0CPUX_CTRL_REG); 135 AWIN_A80_CCU_OFFSET + AWIN_A80_CCU_PLL_C0CPUX_CTRL_REG);
136 const u_int p = (c0cpux & AWIN_A80_CCU_PLL_CxCPUX_OUT_EXT_DIVP) ? 4 : 1; 136 const u_int p = (c0cpux & AWIN_A80_CCU_PLL_CxCPUX_OUT_EXT_DIVP) ? 4 : 1;
137 const u_int n = __SHIFTOUT(c0cpux, AWIN_A80_CCU_PLL_CxCPUX_FACTOR_N); 137 const u_int n = __SHIFTOUT(c0cpux, AWIN_A80_CCU_PLL_CxCPUX_FACTOR_N);
138 138
139 ci->ci_data.cpu_cc_freq = ((uint64_t)AWIN_REF_FREQ * n) / p; 139 ci->ci_data.cpu_cc_freq = ((uint64_t)AWIN_REF_FREQ * n) / p;
140#else 140#else
141 u_int reg = awin_chip_id() == AWIN_CHIP_ID_A31 ? 141 u_int reg = awin_chip_id() == AWIN_CHIP_ID_A31 ?
142 AWIN_A31_CPU_AXI_CFG_REG : 142 AWIN_A31_CPU_AXI_CFG_REG :
143 AWIN_CPU_AHB_APB0_CFG_REG; 143 AWIN_CPU_AHB_APB0_CFG_REG;
144 const uint32_t cpu0_cfg = bus_space_read_4(bst, awin_core_bsh, 144 const uint32_t cpu0_cfg = bus_space_read_4(bst, awin_core_bsh,
145 AWIN_CCM_OFFSET + reg); 145 AWIN_CCM_OFFSET + reg);
146 const u_int cpu_clk_sel = __SHIFTIN(cpu0_cfg, AWIN_CPU_CLK_SRC_SEL); 146 switch (__SHIFTOUT(cpu0_cfg, AWIN_CPU_CLK_SRC_SEL)) {
147 switch (__SHIFTOUT(cpu_clk_sel, AWIN_CPU_CLK_SRC_SEL)) { 
148 case AWIN_CPU_CLK_SRC_SEL_LOSC: 147 case AWIN_CPU_CLK_SRC_SEL_LOSC:
149 ci->ci_data.cpu_cc_freq = 32768; 148 ci->ci_data.cpu_cc_freq = 32768;
150 break; 149 break;
151 case AWIN_CPU_CLK_SRC_SEL_OSC24M: 150 case AWIN_CPU_CLK_SRC_SEL_OSC24M:
152 ci->ci_data.cpu_cc_freq = AWIN_REF_FREQ; 151 ci->ci_data.cpu_cc_freq = AWIN_REF_FREQ;
153 break; 152 break;
154 case AWIN_CPU_CLK_SRC_SEL_PLL1: { 153 case AWIN_CPU_CLK_SRC_SEL_PLL1: {
155 const uint32_t pll1_cfg = bus_space_read_4(bst, 154 const uint32_t pll1_cfg = bus_space_read_4(bst,
156 awin_core_bsh, AWIN_CCM_OFFSET + AWIN_PLL1_CFG_REG); 155 awin_core_bsh, AWIN_CCM_OFFSET + AWIN_PLL1_CFG_REG);
157 u_int p, n, k, m; 156 u_int p, n, k, m;
158 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 157 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
159 p = 0; 158 p = 0;
160 n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N) + 1; 159 n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N) + 1;
161 k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1; 160 k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
162 m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1; 161 m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1;
163 } else { 162 } else {
164 p = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_OUT_EXP_DIVP); 163 p = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_OUT_EXP_DIVP);
165 n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N); 164 n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N);
166 k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1; 165 k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
167 m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1; 166 m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1;
168 } 167 }
169 ci->ci_data.cpu_cc_freq = 168 ci->ci_data.cpu_cc_freq =
170 ((uint64_t)AWIN_REF_FREQ * (n ? n : 1) * k / m) >> p; 169 ((uint64_t)AWIN_REF_FREQ * (n ? n : 1) * k / m) >> p;
171 break; 170 break;
172 } 171 }
173 case AWIN_CPU_CLK_SRC_SEL_200MHZ: 172 case AWIN_CPU_CLK_SRC_SEL_200MHZ:
174 ci->ci_data.cpu_cc_freq = 200000000; 173 ci->ci_data.cpu_cc_freq = 200000000;
175 break; 174 break;
176 } 175 }
177#endif 176#endif
178} 177}
179 178
180void 179void
181awin_bootstrap(vaddr_t iobase, vaddr_t uartbase) 180awin_bootstrap(vaddr_t iobase, vaddr_t uartbase)
182{ 181{
183 int error; 182 int error;
184 bus_space_tag_t bst = &armv7_generic_bs_tag; 183 bus_space_tag_t bst = &armv7_generic_bs_tag;
185 184
186#ifdef AWIN_CONSOLE_EARLY 185#ifdef AWIN_CONSOLE_EARLY
187 uart_base = (volatile uint32_t *)uartbase; 186 uart_base = (volatile uint32_t *)uartbase;
188 cn_tab = &awin_earlycons; 187 cn_tab = &awin_earlycons;
189 printf("Early console started\n"); 188 printf("Early console started\n");
190#endif 189#endif
191 190
192 error = bus_space_map(bst, AWIN_CORE_PBASE, AWIN_CORE_SIZE, 191 error = bus_space_map(bst, AWIN_CORE_PBASE, AWIN_CORE_SIZE,
193 0, &awin_core_bsh); 192 0, &awin_core_bsh);
194 if (error) 193 if (error)
195 panic("%s: failed to map awin %s registers: %d", 194 panic("%s: failed to map awin %s registers: %d",
196 __func__, "io", error); 195 __func__, "io", error);
197 KASSERT(awin_core_bsh == iobase); 196 KASSERT(awin_core_bsh == iobase);
198 197
199#ifdef ALLWINNER_A80 198#ifdef ALLWINNER_A80
200 error = bus_space_map(bst, AWIN_A80_CORE2_PBASE, AWIN_A80_CORE2_SIZE, 199 error = bus_space_map(bst, AWIN_A80_CORE2_PBASE, AWIN_A80_CORE2_SIZE,
201 0, &awin_core2_bsh); 200 0, &awin_core2_bsh);
202 if (error) 201 if (error)
203 panic("%s: failed to map awin %s registers: %d", 202 panic("%s: failed to map awin %s registers: %d",
204 __func__, "core2", error); 203 __func__, "core2", error);
205 error = bus_space_map(bst, AWIN_A80_RCPUS_PBASE, AWIN_A80_RCPUS_SIZE, 204 error = bus_space_map(bst, AWIN_A80_RCPUS_PBASE, AWIN_A80_RCPUS_SIZE,
206 0, &awin_rcpus_bsh); 205 0, &awin_rcpus_bsh);
207 if (error) 206 if (error)
208 panic("%s: failed to map awin %s registers: %d", 207 panic("%s: failed to map awin %s registers: %d",
209 __func__, "rcpus", error); 208 __func__, "rcpus", error);
210#endif 209#endif
211 210
212#ifdef VERBOSE_INIT_ARM 211#ifdef VERBOSE_INIT_ARM
213 printf("CPU Speed is"); 212 printf("CPU Speed is");
214#endif 213#endif
215 awin_cpu_clk(); 214 awin_cpu_clk();
216#ifdef VERBOSE_INIT_ARM 215#ifdef VERBOSE_INIT_ARM
217 printf(" %"PRIu64"\n", curcpu()->ci_data.cpu_cc_freq); 216 printf(" %"PRIu64"\n", curcpu()->ci_data.cpu_cc_freq);
218#endif 217#endif
219 218
220#ifdef VERBOSE_INIT_ARM 219#ifdef VERBOSE_INIT_ARM
221 printf("Determining GPIO configuration"); 220 printf("Determining GPIO configuration");
222#endif 221#endif
223 awin_gpio_init(); 222 awin_gpio_init();
224#ifdef VERBOSE_INIT_ARM 223#ifdef VERBOSE_INIT_ARM
225 printf("\n"); 224 printf("\n");
226#endif 225#endif
227 226
228#ifdef VERBOSE_INIT_ARM 227#ifdef VERBOSE_INIT_ARM
229 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 228 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
230 uint32_t s[4]; 229 uint32_t s[4];
231 unsigned int cpuno; 230 unsigned int cpuno;
232 for (cpuno = 0; cpuno < 4; cpuno++) { 231 for (cpuno = 0; cpuno < 4; cpuno++) {
233 s[cpuno] = bus_space_read_4(bst, awin_core_bsh, 232 s[cpuno] = bus_space_read_4(bst, awin_core_bsh,
234 AWIN_A31_CPUCFG_OFFSET + 233 AWIN_A31_CPUCFG_OFFSET +
235 AWIN_A31_CPUCFG_STATUS_REG(cpuno)); 234 AWIN_A31_CPUCFG_STATUS_REG(cpuno));
236 } 235 }
237 printf("%s: cpu status: 0=%#x 1=%#x 2=%#x 3=%#x\n", __func__, 236 printf("%s: cpu status: 0=%#x 1=%#x 2=%#x 3=%#x\n", __func__,
238 s[0], s[1], s[2], s[3]); 237 s[0], s[1], s[2], s[3]);
239 } else if (awin_chip_id() == AWIN_CHIP_ID_A20) { 238 } else if (awin_chip_id() == AWIN_CHIP_ID_A20) {
240 uint32_t s0 = bus_space_read_4(bst, awin_core_bsh, 239 uint32_t s0 = bus_space_read_4(bst, awin_core_bsh,
241 AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU0_STATUS_REG); 240 AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU0_STATUS_REG);
242 uint32_t s1 = bus_space_read_4(bst, awin_core_bsh, 241 uint32_t s1 = bus_space_read_4(bst, awin_core_bsh,
243 AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU1_STATUS_REG); 242 AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU1_STATUS_REG);
244 printf("%s: cpu status: 0=%#x 1=%#x\n", __func__, s0, s1); 243 printf("%s: cpu status: 0=%#x 1=%#x\n", __func__, s0, s1);
245 } 244 }
246#endif 245#endif
247 246
248#if !defined(MULTIPROCESSOR) && defined(VERBOSE_INIT_ARM) 247#if !defined(MULTIPROCESSOR) && defined(VERBOSE_INIT_ARM)
249 u_int arm_cpu_max; 248 u_int arm_cpu_max;
250#endif 249#endif
251#if defined(MULTIPROCESSOR) || defined(VERBOSE_INIT_ARM) 250#if defined(MULTIPROCESSOR) || defined(VERBOSE_INIT_ARM)
252 arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU); 251 arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU);
253#endif 252#endif
254#ifdef VERBOSE_INIT_ARM 253#ifdef VERBOSE_INIT_ARM
255 printf("%s: %d cpus present\n", __func__, arm_cpu_max); 254 printf("%s: %d cpus present\n", __func__, arm_cpu_max);
256#endif 255#endif
257#if defined(MULTIPROCESSOR) 256#if defined(MULTIPROCESSOR)
258 for (size_t i = 1; i < arm_cpu_max; i++) { 257 for (size_t i = 1; i < arm_cpu_max; i++) {
259 if ((arm_cpu_hatched & (1 << i)) == 0) { 258 if ((arm_cpu_hatched & (1 << i)) == 0) {
260 printf("%s: warning: cpu%zu failed to hatch\n", 259 printf("%s: warning: cpu%zu failed to hatch\n",
261 __func__, i); 260 __func__, i);
262 } 261 }
263 } 262 }
264#endif 263#endif
265} 264}
266 265
267void 266void
268awin_dma_bootstrap(psize_t psize) 267awin_dma_bootstrap(psize_t psize)
269{ 268{
270 awin_coherent_dma_ranges[0].dr_len = psize; 269 awin_coherent_dma_ranges[0].dr_len = psize;
271} 270}
272 271
273#ifdef MULTIPROCESSOR 272#ifdef MULTIPROCESSOR
274void 273void
275awin_cpu_hatch(struct cpu_info *ci) 274awin_cpu_hatch(struct cpu_info *ci)
276{ 275{
277 gtmr_init_cpu_clock(ci); 276 gtmr_init_cpu_clock(ci);
278} 277}
279#endif 278#endif
280 279
281psize_t 280psize_t
282awin_memprobe(void) 281awin_memprobe(void)
283{ 282{
284 psize_t memsize; 283 psize_t memsize;
285 284
286 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 285 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
287#ifdef VERBOSE_INIT_ARM 286#ifdef VERBOSE_INIT_ARM
288 printf("memprobe not supported on A31\n"); 287 printf("memprobe not supported on A31\n");
289#endif 288#endif
290 memsize = 0; 289 memsize = 0;
291 } else { 290 } else {
292 const uint32_t dcr = bus_space_read_4(&armv7_generic_bs_tag, 291 const uint32_t dcr = bus_space_read_4(&armv7_generic_bs_tag,
293 awin_core_bsh, 292 awin_core_bsh,
294 AWIN_DRAM_OFFSET + AWIN_DRAM_DCR_REG); 293 AWIN_DRAM_OFFSET + AWIN_DRAM_DCR_REG);
295 294
296 memsize = (__SHIFTOUT(dcr, AWIN_DRAM_DCR_BUS_WIDTH) + 1) 295 memsize = (__SHIFTOUT(dcr, AWIN_DRAM_DCR_BUS_WIDTH) + 1)
297 / __SHIFTOUT(dcr, AWIN_DRAM_DCR_IO_WIDTH); 296 / __SHIFTOUT(dcr, AWIN_DRAM_DCR_IO_WIDTH);
298 memsize *= 1 << (__SHIFTOUT(dcr, AWIN_DRAM_DCR_CHIP_DENSITY) 297 memsize *= 1 << (__SHIFTOUT(dcr, AWIN_DRAM_DCR_CHIP_DENSITY)
299 + 28 - 3); 298 + 28 - 3);
300#ifdef VERBOSE_INIT_ARM 299#ifdef VERBOSE_INIT_ARM
301 printf("sdram_config = %#x, memsize = %uMB\n", dcr, 300 printf("sdram_config = %#x, memsize = %uMB\n", dcr,
302 (u_int)(memsize >> 20)); 301 (u_int)(memsize >> 20));
303#endif 302#endif
304 } 303 }
305 return memsize; 304 return memsize;
306} 305}
307 306
308uint16_t 307uint16_t
309awin_chip_id(void) 308awin_chip_id(void)
310{ 309{
311 bus_space_tag_t bst = &armv7_generic_bs_tag; 310 bus_space_tag_t bst = &armv7_generic_bs_tag;
312#if defined(ALLWINNER_A80) 311#if defined(ALLWINNER_A80)
313 bus_space_handle_t bsh = awin_core2_bsh; 312 bus_space_handle_t bsh = awin_core2_bsh;
314#else 313#else
315 bus_space_handle_t bsh = awin_core_bsh; 314 bus_space_handle_t bsh = awin_core_bsh;
316#endif 315#endif
317 static uint16_t chip_id = 0; 316 static uint16_t chip_id = 0;
318 uint32_t ver; 317 uint32_t ver;
319 318
320 if (!chip_id) { 319 if (!chip_id) {
321 ver = bus_space_read_4(bst, bsh, 320 ver = bus_space_read_4(bst, bsh,
322 AWIN_SRAM_OFFSET + AWIN_SRAM_VER_REG); 321 AWIN_SRAM_OFFSET + AWIN_SRAM_VER_REG);
323 ver |= AWIN_SRAM_VER_R_EN; 322 ver |= AWIN_SRAM_VER_R_EN;
324 bus_space_write_4(bst, bsh, 323 bus_space_write_4(bst, bsh,
325 AWIN_SRAM_OFFSET + AWIN_SRAM_VER_REG, ver); 324 AWIN_SRAM_OFFSET + AWIN_SRAM_VER_REG, ver);
326 ver = bus_space_read_4(bst, bsh, 325 ver = bus_space_read_4(bst, bsh,
327 AWIN_SRAM_OFFSET + AWIN_SRAM_VER_REG); 326 AWIN_SRAM_OFFSET + AWIN_SRAM_VER_REG);
328 327
329 chip_id = __SHIFTOUT(ver, AWIN_SRAM_VER_KEY_FIELD); 328 chip_id = __SHIFTOUT(ver, AWIN_SRAM_VER_KEY_FIELD);
330 } 329 }
331 330
332 return chip_id; 331 return chip_id;
333} 332}
334 333
335const char * 334const char *
336awin_chip_name(void) 335awin_chip_name(void)
337{ 336{
338 uint16_t chip_id = awin_chip_id(); 337 uint16_t chip_id = awin_chip_id();
339 338
340 switch (chip_id) { 339 switch (chip_id) {
341 case AWIN_CHIP_ID_A10: return "A10"; 340 case AWIN_CHIP_ID_A10: return "A10";
342 case AWIN_CHIP_ID_A13: return "A13"; 341 case AWIN_CHIP_ID_A13: return "A13";
343 case AWIN_CHIP_ID_A20: return "A20"; 342 case AWIN_CHIP_ID_A20: return "A20";
344 case AWIN_CHIP_ID_A23: return "A23"; 343 case AWIN_CHIP_ID_A23: return "A23";
345 case AWIN_CHIP_ID_A31: return "A31"; 344 case AWIN_CHIP_ID_A31: return "A31";
346 case AWIN_CHIP_ID_A80: return "A80"; 345 case AWIN_CHIP_ID_A80: return "A80";
347 default: return "unknown chip"; 346 default: return "unknown chip";
348 } 347 }
349} 348}
350 349
351void 350void
352awin_pll6_enable(void) 351awin_pll6_enable(void)
353{ 352{
354 bus_space_tag_t bst = &armv7_generic_bs_tag; 353 bus_space_tag_t bst = &armv7_generic_bs_tag;
355 bus_space_handle_t bsh = awin_core_bsh; 354 bus_space_handle_t bsh = awin_core_bsh;
356 355
357 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80); 356 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80);
358 357
359 /* 358 /*
360 * SATA needs PLL6 to be a 100MHz clock. 359 * SATA needs PLL6 to be a 100MHz clock.
361 */ 360 */
362 const uint32_t ocfg = bus_space_read_4(bst, bsh, 361 const uint32_t ocfg = bus_space_read_4(bst, bsh,
363 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG); 362 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG);
364 363
365 /* 364 /*
366 * Output freq is 24MHz * n * k / m / 6. 365 * Output freq is 24MHz * n * k / m / 6.
367 * To get to 100MHz, k & m must be equal and n must be 25. 366 * To get to 100MHz, k & m must be equal and n must be 25.
368 */ 367 */
369 uint32_t ncfg = ocfg; 368 uint32_t ncfg = ocfg;
370 ncfg &= ~(AWIN_PLL_CFG_BYPASS); 369 ncfg &= ~(AWIN_PLL_CFG_BYPASS);
371 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 370 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
372 ncfg &= ~(AWIN_PLL_CFG_FACTOR_N|AWIN_PLL_CFG_FACTOR_K); 371 ncfg &= ~(AWIN_PLL_CFG_FACTOR_N|AWIN_PLL_CFG_FACTOR_K);
373 ncfg |= __SHIFTIN(1, AWIN_PLL_CFG_FACTOR_K); 372 ncfg |= __SHIFTIN(1, AWIN_PLL_CFG_FACTOR_K);
374 ncfg |= __SHIFTIN(24, AWIN_PLL_CFG_FACTOR_N); 373 ncfg |= __SHIFTIN(24, AWIN_PLL_CFG_FACTOR_N);
375 } else { 374 } else {
376 const u_int k = __SHIFTOUT(ocfg, AWIN_PLL_CFG_FACTOR_K); 375 const u_int k = __SHIFTOUT(ocfg, AWIN_PLL_CFG_FACTOR_K);
377 ncfg &= ~(AWIN_PLL_CFG_FACTOR_M|AWIN_PLL_CFG_FACTOR_N); 376 ncfg &= ~(AWIN_PLL_CFG_FACTOR_M|AWIN_PLL_CFG_FACTOR_N);
378 ncfg |= __SHIFTIN(k, AWIN_PLL_CFG_FACTOR_M); 377 ncfg |= __SHIFTIN(k, AWIN_PLL_CFG_FACTOR_M);
379 ncfg |= __SHIFTIN(25, AWIN_PLL_CFG_FACTOR_N); 378 ncfg |= __SHIFTIN(25, AWIN_PLL_CFG_FACTOR_N);
380 ncfg |= AWIN_PLL6_CFG_SATA_CLK_EN; 379 ncfg |= AWIN_PLL6_CFG_SATA_CLK_EN;
381 } 380 }
382 ncfg |= AWIN_PLL_CFG_ENABLE; 381 ncfg |= AWIN_PLL_CFG_ENABLE;
383 if (ncfg != ocfg) { 382 if (ncfg != ocfg) {
384 bus_space_write_4(bst, bsh, 383 bus_space_write_4(bst, bsh,
385 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG, ncfg); 384 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG, ncfg);
386 385
387 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 386 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
388 do { 387 do {
389 ncfg = bus_space_read_4(bst, bsh, 388 ncfg = bus_space_read_4(bst, bsh,
390 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG); 389 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG);
391 } while ((ncfg & AWIN_A31_PLL6_CFG_LOCK) == 0); 390 } while ((ncfg & AWIN_A31_PLL6_CFG_LOCK) == 0);
392 } 391 }
393 } 392 }
394#if 0 393#if 0
395 printf(" [pll6=%#x->%#x:n=%ju k=%ju m=%ju] ", 394 printf(" [pll6=%#x->%#x:n=%ju k=%ju m=%ju] ",
396 ocfg, ncfg, 395 ocfg, ncfg,
397 __SHIFTOUT(ncfg, AWIN_PLL_CFG_FACTOR_N), 396 __SHIFTOUT(ncfg, AWIN_PLL_CFG_FACTOR_N),
398 __SHIFTOUT(ncfg, AWIN_PLL_CFG_FACTOR_K), 397 __SHIFTOUT(ncfg, AWIN_PLL_CFG_FACTOR_K),
399 __SHIFTOUT(ncfg, AWIN_PLL_CFG_FACTOR_M)); 398 __SHIFTOUT(ncfg, AWIN_PLL_CFG_FACTOR_M));
400#endif 399#endif
401} 400}
402 401
403void 402void
404awin_pll2_enable(void) 403awin_pll2_enable(void)
405{ 404{
406 bus_space_tag_t bst = &armv7_generic_bs_tag; 405 bus_space_tag_t bst = &armv7_generic_bs_tag;
407 bus_space_handle_t bsh = awin_core_bsh; 406 bus_space_handle_t bsh = awin_core_bsh;
408 407
409 /* 408 /*
410 * AC (at 48kHz) needs PLL2 to be 24576000 Hz 409 * AC (at 48kHz) needs PLL2 to be 24576000 Hz
411 */ 410 */
412 const uint32_t ocfg = bus_space_read_4(bst, bsh, 411 const uint32_t ocfg = bus_space_read_4(bst, bsh,
413 AWIN_CCM_OFFSET + AWIN_PLL2_CFG_REG); 412 AWIN_CCM_OFFSET + AWIN_PLL2_CFG_REG);
414 413
415 uint32_t ncfg = ocfg; 414 uint32_t ncfg = ocfg;
416 415
417 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 416 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
418 ncfg &= ~(AWIN_A31_PLL2_CFG_PREVDIV_M| 417 ncfg &= ~(AWIN_A31_PLL2_CFG_PREVDIV_M|
419 AWIN_A31_PLL2_CFG_FACTOR_N| 418 AWIN_A31_PLL2_CFG_FACTOR_N|
420 AWIN_A31_PLL2_CFG_POSTDIV_P); 419 AWIN_A31_PLL2_CFG_POSTDIV_P);
421 ncfg |= __SHIFTIN(20, AWIN_A31_PLL2_CFG_PREVDIV_M); 420 ncfg |= __SHIFTIN(20, AWIN_A31_PLL2_CFG_PREVDIV_M);
422 ncfg |= __SHIFTIN(85, AWIN_A31_PLL2_CFG_FACTOR_N); 421 ncfg |= __SHIFTIN(85, AWIN_A31_PLL2_CFG_FACTOR_N);
423 ncfg |= __SHIFTIN(3, AWIN_A31_PLL2_CFG_POSTDIV_P); 422 ncfg |= __SHIFTIN(3, AWIN_A31_PLL2_CFG_POSTDIV_P);
424 ncfg |= AWIN_PLL_CFG_ENABLE; 423 ncfg |= AWIN_PLL_CFG_ENABLE;
425 } else { 424 } else {
426 ncfg &= ~(AWIN_PLL2_CFG_PREVDIV| 425 ncfg &= ~(AWIN_PLL2_CFG_PREVDIV|
427 AWIN_PLL2_CFG_FACTOR_N| 426 AWIN_PLL2_CFG_FACTOR_N|
428 AWIN_PLL2_CFG_POSTDIV); 427 AWIN_PLL2_CFG_POSTDIV);
429 ncfg |= __SHIFTIN(21, AWIN_PLL2_CFG_PREVDIV); 428 ncfg |= __SHIFTIN(21, AWIN_PLL2_CFG_PREVDIV);
430 ncfg |= __SHIFTIN(86, AWIN_PLL2_CFG_FACTOR_N); 429 ncfg |= __SHIFTIN(86, AWIN_PLL2_CFG_FACTOR_N);
431 ncfg |= __SHIFTIN(4, AWIN_PLL2_CFG_POSTDIV); 430 ncfg |= __SHIFTIN(4, AWIN_PLL2_CFG_POSTDIV);
432 ncfg |= AWIN_PLL_CFG_ENABLE; 431 ncfg |= AWIN_PLL_CFG_ENABLE;
433 } 432 }
434 433
435 if (ncfg != ocfg) { 434 if (ncfg != ocfg) {
436 bus_space_write_4(bst, bsh, 435 bus_space_write_4(bst, bsh,
437 AWIN_CCM_OFFSET + AWIN_PLL2_CFG_REG, ncfg); 436 AWIN_CCM_OFFSET + AWIN_PLL2_CFG_REG, ncfg);
438 437
439 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 438 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
440 do { 439 do {
441 ncfg = bus_space_read_4(bst, bsh, 440 ncfg = bus_space_read_4(bst, bsh,
442 AWIN_CCM_OFFSET + AWIN_PLL2_CFG_REG); 441 AWIN_CCM_OFFSET + AWIN_PLL2_CFG_REG);
443 } while ((ncfg & AWIN_A31_PLL2_CFG_LOCK) == 0); 442 } while ((ncfg & AWIN_A31_PLL2_CFG_LOCK) == 0);
444 } 443 }
445 } 444 }
446} 445}
447 446
448void 447void
449awin_pll3_enable(void) 448awin_pll3_enable(void)
450{ 449{
451 bus_space_tag_t bst = &armv7_generic_bs_tag; 450 bus_space_tag_t bst = &armv7_generic_bs_tag;
452 bus_space_handle_t bsh = awin_core_bsh; 451 bus_space_handle_t bsh = awin_core_bsh;
453 452
454 /* 453 /*
455 * HDMI needs PLL3 to be 29700000 Hz 454 * HDMI needs PLL3 to be 29700000 Hz
456 */ 455 */
457 const uint32_t ocfg = bus_space_read_4(bst, bsh, 456 const uint32_t ocfg = bus_space_read_4(bst, bsh,
458 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG); 457 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG);
459 458
460 uint32_t ncfg = ocfg; 459 uint32_t ncfg = ocfg;
461 460
462 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 461 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
463 ncfg &= ~AWIN_A31_PLL3_CFG_MODE; 462 ncfg &= ~AWIN_A31_PLL3_CFG_MODE;
464 ncfg &= ~AWIN_A31_PLL3_CFG_MODE_SEL; 463 ncfg &= ~AWIN_A31_PLL3_CFG_MODE_SEL;
465 ncfg |= AWIN_A31_PLL3_CFG_FRAC_CLK_OUT; 464 ncfg |= AWIN_A31_PLL3_CFG_FRAC_CLK_OUT;
466 ncfg |= AWIN_PLL_CFG_ENABLE; 465 ncfg |= AWIN_PLL_CFG_ENABLE;
467 } else { 466 } else {
468 ncfg &= ~AWIN_PLL3_MODE_SEL; 467 ncfg &= ~AWIN_PLL3_MODE_SEL;
469 ncfg |= AWIN_PLL3_FRAC_SET; 468 ncfg |= AWIN_PLL3_FRAC_SET;
470 ncfg |= AWIN_PLL_CFG_ENABLE; 469 ncfg |= AWIN_PLL_CFG_ENABLE;
471 } 470 }
472 471
473 if (ncfg != ocfg) { 472 if (ncfg != ocfg) {
474 bus_space_write_4(bst, bsh, 473 bus_space_write_4(bst, bsh,
475 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG, ncfg); 474 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG, ncfg);
476 475
477 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 476 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
478 do { 477 do {
479 ncfg = bus_space_read_4(bst, bsh, 478 ncfg = bus_space_read_4(bst, bsh,
480 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG); 479 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG);
481 } while ((ncfg & AWIN_A31_PLL3_CFG_LOCK) == 0); 480 } while ((ncfg & AWIN_A31_PLL3_CFG_LOCK) == 0);
482 } 481 }
483 } 482 }
484} 483}
485 484
486void 485void
487awin_pll7_enable(void) 486awin_pll7_enable(void)
488{ 487{
489 bus_space_tag_t bst = &armv7_generic_bs_tag; 488 bus_space_tag_t bst = &armv7_generic_bs_tag;
490 bus_space_handle_t bsh = awin_core_bsh; 489 bus_space_handle_t bsh = awin_core_bsh;
491 490
492 /* 491 /*
493 * HDMI needs PLL7 to be 29700000 Hz 492 * HDMI needs PLL7 to be 29700000 Hz
494 */ 493 */
495 const uint32_t ocfg = bus_space_read_4(bst, bsh, 494 const uint32_t ocfg = bus_space_read_4(bst, bsh,
496 AWIN_CCM_OFFSET + AWIN_PLL7_CFG_REG); 495 AWIN_CCM_OFFSET + AWIN_PLL7_CFG_REG);
497 496
498 uint32_t ncfg = ocfg; 497 uint32_t ncfg = ocfg;
499 498
500 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 499 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
501 ncfg &= ~AWIN_A31_PLL7_CFG_MODE; 500 ncfg &= ~AWIN_A31_PLL7_CFG_MODE;
502 ncfg &= ~AWIN_A31_PLL7_CFG_MODE_SEL; 501 ncfg &= ~AWIN_A31_PLL7_CFG_MODE_SEL;
503 ncfg |= AWIN_A31_PLL7_CFG_FRAC_CLK_OUT; 502 ncfg |= AWIN_A31_PLL7_CFG_FRAC_CLK_OUT;
504 ncfg |= AWIN_PLL_CFG_ENABLE; 503 ncfg |= AWIN_PLL_CFG_ENABLE;
505 } else { 504 } else {
506 ncfg &= ~AWIN_PLL7_MODE_SEL; 505 ncfg &= ~AWIN_PLL7_MODE_SEL;
507 ncfg |= AWIN_PLL7_FRAC_SET; 506 ncfg |= AWIN_PLL7_FRAC_SET;
508 ncfg |= AWIN_PLL_CFG_ENABLE; 507 ncfg |= AWIN_PLL_CFG_ENABLE;
509 } 508 }
510 509
511 if (ncfg != ocfg) { 510 if (ncfg != ocfg) {
512 bus_space_write_4(bst, bsh, 511 bus_space_write_4(bst, bsh,
513 AWIN_CCM_OFFSET + AWIN_PLL7_CFG_REG, ncfg); 512 AWIN_CCM_OFFSET + AWIN_PLL7_CFG_REG, ncfg);
514 513
515 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 514 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
516 do { 515 do {
517 ncfg = bus_space_read_4(bst, bsh, 516 ncfg = bus_space_read_4(bst, bsh,
518 AWIN_CCM_OFFSET + AWIN_PLL7_CFG_REG); 517 AWIN_CCM_OFFSET + AWIN_PLL7_CFG_REG);
519 } while ((ncfg & AWIN_A31_PLL7_CFG_LOCK) == 0); 518 } while ((ncfg & AWIN_A31_PLL7_CFG_LOCK) == 0);
520 } 519 }
521 } 520 }
522} 521}
523 522
524void 523void
525awin_pll3_set_rate(uint32_t rate) 524awin_pll3_set_rate(uint32_t rate)
526{ 525{
527 bus_space_tag_t bst = &armv7_generic_bs_tag; 526 bus_space_tag_t bst = &armv7_generic_bs_tag;
528 bus_space_handle_t bsh = awin_core_bsh; 527 bus_space_handle_t bsh = awin_core_bsh;
529 528
530 const uint32_t ocfg = bus_space_read_4(bst, bsh, 529 const uint32_t ocfg = bus_space_read_4(bst, bsh,
531 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG); 530 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG);
532 531
533 uint32_t ncfg = ocfg; 532 uint32_t ncfg = ocfg;
534 if (rate == 0) { 533 if (rate == 0) {
535 ncfg &= ~AWIN_PLL_CFG_ENABLE; 534 ncfg &= ~AWIN_PLL_CFG_ENABLE;
536 } else { 535 } else {
537 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 536 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
538 unsigned int m = 8; 537 unsigned int m = 8;
539 unsigned int n = rate / (AWIN_REF_FREQ / m); 538 unsigned int n = rate / (AWIN_REF_FREQ / m);
540 ncfg |= AWIN_A31_PLL3_CFG_MODE_SEL; 539 ncfg |= AWIN_A31_PLL3_CFG_MODE_SEL;
541 ncfg &= ~AWIN_A31_PLL3_CFG_FACTOR_N; 540 ncfg &= ~AWIN_A31_PLL3_CFG_FACTOR_N;
542 ncfg |= __SHIFTIN(n - 1, AWIN_A31_PLL3_CFG_FACTOR_N); 541 ncfg |= __SHIFTIN(n - 1, AWIN_A31_PLL3_CFG_FACTOR_N);
543 ncfg &= ~AWIN_A31_PLL3_CFG_PREDIV_M; 542 ncfg &= ~AWIN_A31_PLL3_CFG_PREDIV_M;
544 ncfg |= __SHIFTIN(m - 1, AWIN_A31_PLL3_CFG_PREDIV_M); 543 ncfg |= __SHIFTIN(m - 1, AWIN_A31_PLL3_CFG_PREDIV_M);
545 } else { 544 } else {
546 unsigned int m = rate / 3000000; 545 unsigned int m = rate / 3000000;
547 ncfg |= AWIN_PLL3_MODE_SEL; 546 ncfg |= AWIN_PLL3_MODE_SEL;
548 ncfg &= ~AWIN_PLL3_FACTOR_M; 547 ncfg &= ~AWIN_PLL3_FACTOR_M;
549 ncfg |= __SHIFTIN(m, AWIN_PLL3_FACTOR_M); 548 ncfg |= __SHIFTIN(m, AWIN_PLL3_FACTOR_M);
550 } 549 }
551 ncfg |= AWIN_PLL_CFG_ENABLE; 550 ncfg |= AWIN_PLL_CFG_ENABLE;
552 } 551 }
553 552
554 if (ncfg != ocfg) { 553 if (ncfg != ocfg) {
555 bus_space_write_4(bst, bsh, 554 bus_space_write_4(bst, bsh,
556 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG, ncfg); 555 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG, ncfg);
557 556
558 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 557 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
559 do { 558 do {
560 ncfg = bus_space_read_4(bst, bsh, 559 ncfg = bus_space_read_4(bst, bsh,
561 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG); 560 AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG);
562 } while ((ncfg & AWIN_A31_PLL3_CFG_LOCK) == 0); 561 } while ((ncfg & AWIN_A31_PLL3_CFG_LOCK) == 0);
563 } 562 }
564 } 563 }
565} 564}
566 565
567uint32_t 566uint32_t
568awin_pll5x_get_rate(void) 567awin_pll5x_get_rate(void)
569{ 568{
570 bus_space_tag_t bst = &armv7_generic_bs_tag; 569 bus_space_tag_t bst = &armv7_generic_bs_tag;
571 bus_space_handle_t bsh = awin_core_bsh; 570 bus_space_handle_t bsh = awin_core_bsh;
572 unsigned int n, k, p; 571 unsigned int n, k, p;
573 572
574 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A31); 573 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A31);
575 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80); 574 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80);
576 575
577 const uint32_t cfg = bus_space_read_4(bst, bsh, 576 const uint32_t cfg = bus_space_read_4(bst, bsh,
578 AWIN_CCM_OFFSET + AWIN_PLL5_CFG_REG); 577 AWIN_CCM_OFFSET + AWIN_PLL5_CFG_REG);
579 578
580 n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N); 579 n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N);
581 k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1; 580 k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
582 p = __SHIFTOUT(cfg, AWIN_PLL5_OUT_EXT_DIV_P); 581 p = __SHIFTOUT(cfg, AWIN_PLL5_OUT_EXT_DIV_P);
583 582
584 return (AWIN_REF_FREQ * n * k) >> p; 583 return (AWIN_REF_FREQ * n * k) >> p;
585} 584}
586 585
587uint32_t 586uint32_t
588awin_pll6_get_rate(void) 587awin_pll6_get_rate(void)
589{ 588{
590 bus_space_tag_t bst = &armv7_generic_bs_tag; 589 bus_space_tag_t bst = &armv7_generic_bs_tag;
591 bus_space_handle_t bsh = awin_core_bsh; 590 bus_space_handle_t bsh = awin_core_bsh;
592 unsigned int n, k, m; 591 unsigned int n, k, m;
593 592
594 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80); 593 KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80);
595 594
596 const uint32_t cfg = bus_space_read_4(bst, bsh, 595 const uint32_t cfg = bus_space_read_4(bst, bsh,
597 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG); 596 AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG);
598 597
599 if (awin_chip_id() == AWIN_CHIP_ID_A31) { 598 if (awin_chip_id() == AWIN_CHIP_ID_A31) {
600 n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N) + 1; 599 n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N) + 1;
601 k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1; 600 k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
602 m = 2; 601 m = 2;
603 } else { 602 } else {
604 n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N); 603 n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N);
605 k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1; 604 k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
606 m = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_M) + 1; 605 m = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_M) + 1;
607 } 606 }
608 607
609 return (AWIN_REF_FREQ * n * k) / m; 608 return (AWIN_REF_FREQ * n * k) / m;
610} 609}
611 610
612uint32_t 611uint32_t
613awin_periph0_get_rate(void) 612awin_periph0_get_rate(void)
614{ 613{
615 bus_space_tag_t bst = &armv7_generic_bs_tag; 614 bus_space_tag_t bst = &armv7_generic_bs_tag;
616 bus_space_handle_t bsh = awin_core_bsh; 615 bus_space_handle_t bsh = awin_core_bsh;
617 unsigned int n, idiv, odiv; 616 unsigned int n, idiv, odiv;
618 617
619 KASSERT(awin_chip_id() == AWIN_CHIP_ID_A80); 618 KASSERT(awin_chip_id() == AWIN_CHIP_ID_A80);
620 619
621 const uint32_t cfg = bus_space_read_4(bst, bsh, 620 const uint32_t cfg = bus_space_read_4(bst, bsh,
622 AWIN_A80_CCU_OFFSET + AWIN_A80_CCU_PLL_PERIPH0_CTRL_REG); 621 AWIN_A80_CCU_OFFSET + AWIN_A80_CCU_PLL_PERIPH0_CTRL_REG);
623 622
624 n = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_FACTOR_N); 623 n = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_FACTOR_N);
625 idiv = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_INPUT_DIV) + 1; 624 idiv = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_INPUT_DIV) + 1;
626 odiv = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_OUTPUT_DIV) + 1; 625 odiv = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_OUTPUT_DIV) + 1;
627 626
628 return ((AWIN_REF_FREQ * n) / idiv) / odiv; 627 return ((AWIN_REF_FREQ * n) / idiv) / odiv;
629} 628}