ar933x_chip.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: stable/11/sys/mips/atheros/ar933x_chip.c 330897 2018-03-14 03:19:51Z eadler $"); 31 32#include "opt_ddb.h" 33 34#include <sys/param.h> 35#include <sys/conf.h> 36#include <sys/kernel.h> 37#include <sys/systm.h> 38#include <sys/bus.h> 39#include <sys/cons.h> 40#include <sys/kdb.h> 41#include <sys/reboot.h> 42 43#include <vm/vm.h> 44#include <vm/vm_page.h> 45 46#include <net/ethernet.h> 47 48#include <machine/clock.h> 49#include <machine/cpu.h> 50#include <machine/cpuregs.h> 51#include <machine/hwfunc.h> 52#include <machine/md_var.h> 53#include <machine/trap.h> 54#include <machine/vmparam.h> 55 56#include <mips/atheros/ar71xxreg.h> 57#include <mips/atheros/ar933xreg.h> 58 59#include <mips/atheros/ar71xx_cpudef.h> 60#include <mips/atheros/ar71xx_setup.h> 61 62#include <mips/atheros/ar71xx_chip.h> 63#include <mips/atheros/ar933x_chip.h> 64 65static void 66ar933x_chip_detect_mem_size(void) 67{ 68} 69 70static void 71ar933x_chip_detect_sys_frequency(void) 72{ 73 uint32_t clock_ctrl; 74 uint32_t cpu_config; 75 uint32_t freq; 76 uint32_t t; 77 78 t = ATH_READ_REG(AR933X_RESET_REG_BOOTSTRAP); 79 if (t & AR933X_BOOTSTRAP_REF_CLK_40) 80 u_ar71xx_refclk = (40 * 1000 * 1000); 81 else 82 u_ar71xx_refclk = (25 * 1000 * 1000); 83 84 clock_ctrl = ATH_READ_REG(AR933X_PLL_CLOCK_CTRL_REG); 85 if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 86 u_ar71xx_cpu_freq = u_ar71xx_refclk; 87 u_ar71xx_ahb_freq = u_ar71xx_refclk; 88 u_ar71xx_ddr_freq = u_ar71xx_refclk; 89 } else { 90 cpu_config = ATH_READ_REG(AR933X_PLL_CPU_CONFIG_REG); 91 92 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 93 AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 94 freq = u_ar71xx_refclk / t; 95 96 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 97 AR933X_PLL_CPU_CONFIG_NINT_MASK; 98 freq *= t; 99 100 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 101 AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 102 if (t == 0) 103 t = 1; 104 105 freq >>= t; 106 107 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 108 AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 109 u_ar71xx_cpu_freq = freq / t; 110 111 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 112 AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 113 u_ar71xx_ddr_freq = freq / t; 114 115 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 116 AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 117 u_ar71xx_ahb_freq = freq / t; 118 } 119 120 /* 121 * On the AR933x, the UART frequency is the reference clock, 122 * not the AHB bus clock. 123 */ 124 u_ar71xx_uart_freq = u_ar71xx_refclk; 125 126 /* 127 * XXX TODO: check whether the mdio frequency is always the 128 * refclock frequency, or whether it's variable like on the 129 * AR934x. 130 */ 131 u_ar71xx_mdio_freq = u_ar71xx_refclk; 132 133 /* 134 * XXX check what the watchdog frequency should be? 135 */ 136 u_ar71xx_wdt_freq = u_ar71xx_ahb_freq; 137} 138 139static void 140ar933x_chip_device_stop(uint32_t mask) 141{ 142 uint32_t reg; 143 144 reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE); 145 ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg | mask); 146} 147 148static void 149ar933x_chip_device_start(uint32_t mask) 150{ 151 uint32_t reg; 152 153 reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE); 154 ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg & ~mask); 155} 156 157static int 158ar933x_chip_device_stopped(uint32_t mask) 159{ 160 uint32_t reg; 161 162 reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE); 163 return ((reg & mask) == mask); 164} 165 166static void 167ar933x_chip_set_mii_speed(uint32_t unit, uint32_t speed) 168{ 169 170 /* XXX TODO */ 171 return; 172} 173 174/* 175 * XXX TODO !! 176 */ 177static void 178ar933x_chip_set_pll_ge(int unit, int speed, uint32_t pll) 179{ 180 181 switch (unit) { 182 case 0: 183 /* XXX TODO */ 184 break; 185 case 1: 186 /* XXX TODO */ 187 break; 188 default: 189 printf("%s: invalid PLL set for arge unit: %d\n", 190 __func__, unit); 191 return; 192 } 193} 194 195static void 196ar933x_chip_ddr_flush(ar71xx_flush_ddr_id_t id) 197{ 198 199 switch (id) { 200 case AR71XX_CPU_DDR_FLUSH_GE0: 201 ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0); 202 break; 203 case AR71XX_CPU_DDR_FLUSH_GE1: 204 ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1); 205 break; 206 case AR71XX_CPU_DDR_FLUSH_USB: 207 ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB); 208 break; 209 case AR71XX_CPU_DDR_FLUSH_WMAC: 210 ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC); 211 break; 212 default: 213 printf("%s: invalid DDR flush id (%d)\n", __func__, id); 214 break; 215 } 216} 217 218 219static uint32_t 220ar933x_chip_get_eth_pll(unsigned int mac, int speed) 221{ 222 uint32_t pll; 223 224 switch (speed) { 225 case 10: 226 pll = AR933X_PLL_VAL_10; 227 break; 228 case 100: 229 pll = AR933X_PLL_VAL_100; 230 break; 231 case 1000: 232 pll = AR933X_PLL_VAL_1000; 233 break; 234 default: 235 printf("%s%d: invalid speed %d\n", __func__, mac, speed); 236 pll = 0; 237 } 238 return (pll); 239} 240 241static void 242ar933x_chip_init_usb_peripheral(void) 243{ 244 ar71xx_device_stop(AR933X_RESET_USBSUS_OVERRIDE); 245 DELAY(100); 246 247 ar71xx_device_start(AR933X_RESET_USB_HOST); 248 DELAY(100); 249 250 ar71xx_device_start(AR933X_RESET_USB_PHY); 251 DELAY(100); 252} 253 254static void 255ar933x_configure_gmac(uint32_t gmac_cfg) 256{ 257 uint32_t reg; 258 259 reg = ATH_READ_REG(AR933X_GMAC_REG_ETH_CFG); 260 261 /* 262 * The relevant bits here include: 263 * 264 * + AR933X_ETH_CFG_SW_PHY_SWAP 265 * + AR933X_ETH_CFG_SW_PHY_ADDR_SWAP 266 * 267 * There are other things; look at what openwrt exposes so 268 * it can be correctly exposed. 269 * 270 * TODO: what about ethernet switch support? How's that work? 271 */ 272 if (bootverbose) 273 printf("%s: GMAC config was 0x%08x\n", __func__, reg); 274 reg &= ~(AR933X_ETH_CFG_SW_PHY_SWAP | AR933X_ETH_CFG_SW_PHY_ADDR_SWAP); 275 reg |= gmac_cfg; 276 if (bootverbose) 277 printf("%s: GMAC setting is 0x%08x; register is now 0x%08x\n", 278 __func__, 279 gmac_cfg, 280 reg); 281 ATH_WRITE_REG(AR933X_GMAC_REG_ETH_CFG, reg); 282} 283 284static void 285ar933x_chip_init_gmac(void) 286{ 287 int val; 288 uint32_t gmac_cfg = 0; 289 290 /* 291 * These two bits need a bit better explanation. 292 * 293 * The default configuration in the hardware is to map both 294 * ports to the internal switch. 295 * 296 * Here, GE0 == arge0, GE1 == arge1. 297 * 298 * The internal switch has: 299 * + 5 MAC ports, MAC0->MAC4. 300 * + 5 PHY ports, PHY0->PHY4, 301 * + MAC0 connects to GE1; 302 * + GE0 connects to PHY4; 303 * + The other mappings are MAC1->PHY0, MAC2->PHY1 .. MAC4->PHY3. 304 * 305 * The GE1 port is linked in via 1000MBit/full, supplying what is 306 * normally the 'WAN' switch ports. 307 * 308 * The switch is connected the MDIO bus on GE1. It looks like 309 * a normal AR7240 on-board switch. 310 * 311 * The GE0 port is connected via MII to PHY4, and can operate in 312 * 10/100mbit, full/half duplex. Ie, you can speak to PHY4 on 313 * the MDIO bus and everything will simply 'work'. 314 * 315 * So far so good. This looks just like an AR7240 SoC. 316 * 317 * However, some configurations will just expose one or two 318 * physical ports. In this case, some configuration bits can 319 * be set to tweak this. 320 * 321 * + CFG_SW_PHY_ADDR_SWAP swaps PHY port 0 with PHY port 4. 322 * Ie, GE0's PHY shows up as PHY 0. So if there's only 323 * one physical port, there's no need to involve the 324 * switch framework - it can just show up as a default, 325 * normal single PHY. 326 * 327 * + CFG_SW_PHY_SWAP swaps the internal switch connection 328 * between PHY0 and PHY4. Ie, PHY4 connects to MAc1, 329 * PHY0 connects to GE0. 330 */ 331 if ((resource_int_value("ar933x_gmac", 0, "override_phy", &val) == 0) 332 && (val == 0)) 333 return; 334 if ((resource_int_value("ar933x_gmac", 0, "swap_phy", &val) == 0) 335 && (val == 1)) 336 gmac_cfg |= AR933X_ETH_CFG_SW_PHY_SWAP; 337 if ((resource_int_value("ar933x_gmac", 0, "swap_phy_addr", &val) == 0) 338 && (val == 1)) 339 gmac_cfg |= AR933X_ETH_CFG_SW_PHY_ADDR_SWAP; 340 ar933x_configure_gmac(gmac_cfg); 341} 342 343struct ar71xx_cpu_def ar933x_chip_def = { 344 &ar933x_chip_detect_mem_size, 345 &ar933x_chip_detect_sys_frequency, 346 &ar933x_chip_device_stop, 347 &ar933x_chip_device_start, 348 &ar933x_chip_device_stopped, 349 &ar933x_chip_set_pll_ge, 350 &ar933x_chip_set_mii_speed, 351 &ar71xx_chip_set_mii_if, 352 &ar933x_chip_get_eth_pll, 353 &ar933x_chip_ddr_flush, 354 &ar933x_chip_init_usb_peripheral, 355 NULL, 356 NULL, 357 &ar933x_chip_init_gmac, 358}; 359