ar934x_chip.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2013 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/ar934x_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/ar934xreg.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/ar934x_chip.h> 64 65static void 66ar934x_chip_detect_mem_size(void) 67{ 68} 69 70static uint32_t 71ar934x_get_pll_freq(uint32_t ref, uint32_t ref_div, uint32_t nint, 72 uint32_t nfrac, uint32_t frac, uint32_t out_div) 73{ 74 uint64_t t; 75 uint32_t ret; 76 77 t = u_ar71xx_refclk; 78 t *= nint; 79 t = t / ref_div; 80 ret = t; 81 82 t = u_ar71xx_refclk; 83 t *= nfrac; 84 t = t / (ref_div * frac); 85 ret += t; 86 87 ret /= (1 << out_div); 88 return (ret); 89} 90 91static void 92ar934x_chip_detect_sys_frequency(void) 93{ 94 uint32_t pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 95 uint32_t cpu_pll, ddr_pll; 96 uint32_t bootstrap; 97 uint32_t reg; 98 99 bootstrap = ATH_READ_REG(AR934X_RESET_REG_BOOTSTRAP); 100 if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 101 u_ar71xx_refclk = 40 * 1000 * 1000; 102 else 103 u_ar71xx_refclk = 25 * 1000 * 1000; 104 105 pll = ATH_READ_REG(AR934X_SRIF_CPU_DPLL2_REG); 106 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 107 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 108 AR934X_SRIF_DPLL2_OUTDIV_MASK; 109 pll = ATH_READ_REG(AR934X_SRIF_CPU_DPLL1_REG); 110 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 111 AR934X_SRIF_DPLL1_NINT_MASK; 112 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 113 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 114 AR934X_SRIF_DPLL1_REFDIV_MASK; 115 frac = 1 << 18; 116 } else { 117 pll = ATH_READ_REG(AR934X_PLL_CPU_CONFIG_REG); 118 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 119 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 120 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 121 AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 122 nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 123 AR934X_PLL_CPU_CONFIG_NINT_MASK; 124 nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 125 AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 126 frac = 1 << 6; 127 } 128 129 cpu_pll = ar934x_get_pll_freq(u_ar71xx_refclk, ref_div, nint, 130 nfrac, frac, out_div); 131 132 pll = ATH_READ_REG(AR934X_SRIF_DDR_DPLL2_REG); 133 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 134 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 135 AR934X_SRIF_DPLL2_OUTDIV_MASK; 136 pll = ATH_READ_REG(AR934X_SRIF_DDR_DPLL1_REG); 137 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 138 AR934X_SRIF_DPLL1_NINT_MASK; 139 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 140 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 141 AR934X_SRIF_DPLL1_REFDIV_MASK; 142 frac = 1 << 18; 143 } else { 144 pll = ATH_READ_REG(AR934X_PLL_DDR_CONFIG_REG); 145 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 146 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 147 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 148 AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 149 nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 150 AR934X_PLL_DDR_CONFIG_NINT_MASK; 151 nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 152 AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 153 frac = 1 << 10; 154 } 155 156 ddr_pll = ar934x_get_pll_freq(u_ar71xx_refclk, ref_div, nint, 157 nfrac, frac, out_div); 158 159 clk_ctrl = ATH_READ_REG(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 160 161 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 162 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 163 164 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 165 u_ar71xx_cpu_freq = u_ar71xx_refclk; 166 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 167 u_ar71xx_cpu_freq = cpu_pll / (postdiv + 1); 168 else 169 u_ar71xx_cpu_freq = ddr_pll / (postdiv + 1); 170 171 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 172 AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 173 174 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 175 u_ar71xx_ddr_freq = u_ar71xx_refclk; 176 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 177 u_ar71xx_ddr_freq = ddr_pll / (postdiv + 1); 178 else 179 u_ar71xx_ddr_freq = cpu_pll / (postdiv + 1); 180 181 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 182 AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 183 184 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 185 u_ar71xx_ahb_freq = u_ar71xx_refclk; 186 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 187 u_ar71xx_ahb_freq = ddr_pll / (postdiv + 1); 188 else 189 u_ar71xx_ahb_freq = cpu_pll / (postdiv + 1); 190 191 u_ar71xx_wdt_freq = u_ar71xx_refclk; 192 u_ar71xx_uart_freq = u_ar71xx_refclk; 193 194 /* 195 * Next, fetch reference clock speed for MDIO bus. 196 */ 197 reg = ATH_READ_REG(AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); 198 if (reg & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) { 199 printf("%s: mdio=100MHz\n", __func__); 200 u_ar71xx_mdio_freq = (100 * 1000 * 1000); 201 } else { 202 printf("%s: mdio=%d Hz\n", __func__, u_ar71xx_refclk); 203 u_ar71xx_mdio_freq = u_ar71xx_refclk; 204 } 205} 206 207static void 208ar934x_chip_device_stop(uint32_t mask) 209{ 210 uint32_t reg; 211 212 reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE); 213 ATH_WRITE_REG(AR934X_RESET_REG_RESET_MODULE, reg | mask); 214} 215 216static void 217ar934x_chip_device_start(uint32_t mask) 218{ 219 uint32_t reg; 220 221 reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE); 222 ATH_WRITE_REG(AR934X_RESET_REG_RESET_MODULE, reg & ~mask); 223} 224 225static int 226ar934x_chip_device_stopped(uint32_t mask) 227{ 228 uint32_t reg; 229 230 reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE); 231 return ((reg & mask) == mask); 232} 233 234static void 235ar934x_chip_set_mii_speed(uint32_t unit, uint32_t speed) 236{ 237 238 /* XXX TODO */ 239 return; 240} 241 242/* 243 * XXX TODO !! 244 */ 245static void 246ar934x_chip_set_pll_ge(int unit, int speed, uint32_t pll) 247{ 248 249 switch (unit) { 250 case 0: 251 ATH_WRITE_REG(AR934X_PLL_ETH_XMII_CONTROL_REG, pll); 252 break; 253 case 1: 254 /* XXX nothing */ 255 break; 256 default: 257 printf("%s: invalid PLL set for arge unit: %d\n", 258 __func__, unit); 259 return; 260 } 261} 262 263static void 264ar934x_chip_ddr_flush(ar71xx_flush_ddr_id_t id) 265{ 266 267 switch (id) { 268 case AR71XX_CPU_DDR_FLUSH_GE0: 269 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_GE0); 270 break; 271 case AR71XX_CPU_DDR_FLUSH_GE1: 272 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_GE1); 273 break; 274 case AR71XX_CPU_DDR_FLUSH_USB: 275 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_USB); 276 break; 277 case AR71XX_CPU_DDR_FLUSH_PCIE: 278 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); 279 break; 280 case AR71XX_CPU_DDR_FLUSH_WMAC: 281 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_WMAC); 282 break; 283 default: 284 printf("%s: invalid DDR flush id (%d)\n", __func__, id); 285 break; 286 } 287} 288 289 290static uint32_t 291ar934x_chip_get_eth_pll(unsigned int mac, int speed) 292{ 293 uint32_t pll; 294 295 switch (speed) { 296 case 10: 297 pll = AR934X_PLL_VAL_10; 298 break; 299 case 100: 300 pll = AR934X_PLL_VAL_100; 301 break; 302 case 1000: 303 pll = AR934X_PLL_VAL_1000; 304 break; 305 default: 306 printf("%s%d: invalid speed %d\n", __func__, mac, speed); 307 pll = 0; 308 } 309 return (pll); 310} 311 312static void 313ar934x_chip_reset_ethernet_switch(void) 314{ 315 316 ar71xx_device_stop(AR934X_RESET_ETH_SWITCH); 317 DELAY(100); 318 ar71xx_device_start(AR934X_RESET_ETH_SWITCH); 319 DELAY(100); 320} 321 322static void 323ar934x_configure_gmac(uint32_t gmac_cfg) 324{ 325 uint32_t reg; 326 327 reg = ATH_READ_REG(AR934X_GMAC_REG_ETH_CFG); 328 printf("%s: ETH_CFG=0x%08x\n", __func__, reg); 329 330 reg &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | 331 AR934X_ETH_CFG_MII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE | 332 AR934X_ETH_CFG_SW_PHY_SWAP); 333 334 reg |= gmac_cfg; 335 336 ATH_WRITE_REG(AR934X_GMAC_REG_ETH_CFG, reg); 337} 338 339static void 340ar934x_chip_init_usb_peripheral(void) 341{ 342 uint32_t reg; 343 344 reg = ATH_READ_REG(AR934X_RESET_REG_BOOTSTRAP); 345 if (reg & AR934X_BOOTSTRAP_USB_MODE_DEVICE) 346 return; 347 348 ar71xx_device_stop(AR934X_RESET_USBSUS_OVERRIDE); 349 DELAY(100); 350 351 ar71xx_device_start(AR934X_RESET_USB_PHY); 352 DELAY(100); 353 354 ar71xx_device_start(AR934X_RESET_USB_PHY_ANALOG); 355 DELAY(100); 356 357 ar71xx_device_start(AR934X_RESET_USB_HOST); 358 DELAY(100); 359} 360 361static void 362ar934x_chip_set_mii_if(uint32_t unit, uint32_t mii_mode) 363{ 364 365 /* 366 * XXX ! 367 * 368 * Nothing to see here; although gmac0 can have its 369 * MII configuration changed, the register values 370 * are slightly different. 371 */ 372} 373 374/* 375 * XXX TODO: fetch default MII divider configuration 376 */ 377 378static void 379ar934x_chip_reset_wmac(void) 380{ 381 382 /* XXX TODO */ 383} 384 385static void 386ar934x_chip_init_gmac(void) 387{ 388 long gmac_cfg; 389 390 if (resource_long_value("ar934x_gmac", 0, "gmac_cfg", 391 &gmac_cfg) == 0) { 392 printf("%s: gmac_cfg=0x%08lx\n", 393 __func__, 394 (long) gmac_cfg); 395 ar934x_configure_gmac((uint32_t) gmac_cfg); 396 } 397} 398 399/* 400 * Reset the NAND Flash Controller. 401 * 402 * + active=1 means "make it active". 403 * + active=0 means "make it inactive". 404 */ 405static void 406ar934x_chip_reset_nfc(int active) 407{ 408 409 if (active) { 410 ar71xx_device_start(AR934X_RESET_NANDF); 411 DELAY(100); 412 413 ar71xx_device_start(AR934X_RESET_ETH_SWITCH_ANALOG); 414 DELAY(250); 415 } else { 416 ar71xx_device_stop(AR934X_RESET_ETH_SWITCH_ANALOG); 417 DELAY(250); 418 419 ar71xx_device_stop(AR934X_RESET_NANDF); 420 DELAY(100); 421 } 422} 423 424/* 425 * Configure the GPIO output mux setup. 426 * 427 * The AR934x introduced an output mux which allowed 428 * certain functions to be configured on any pin. 429 * Specifically, the switch PHY link LEDs and 430 * WMAC external RX LNA switches are not limited to 431 * a specific GPIO pin. 432 */ 433static void 434ar934x_chip_gpio_output_configure(int gpio, uint8_t func) 435{ 436 uint32_t reg, s; 437 uint32_t t; 438 439 if (gpio > AR934X_GPIO_COUNT) 440 return; 441 442 reg = AR934X_GPIO_REG_OUT_FUNC0 + rounddown(gpio, 4); 443 s = 8 * (gpio % 4); 444 445 /* read-modify-write */ 446 t = ATH_READ_REG(AR71XX_GPIO_BASE + reg); 447 t &= ~(0xff << s); 448 t |= func << s; 449 ATH_WRITE_REG(AR71XX_GPIO_BASE + reg, t); 450 451 /* flush write */ 452 ATH_READ_REG(AR71XX_GPIO_BASE + reg); 453} 454 455struct ar71xx_cpu_def ar934x_chip_def = { 456 &ar934x_chip_detect_mem_size, 457 &ar934x_chip_detect_sys_frequency, 458 &ar934x_chip_device_stop, 459 &ar934x_chip_device_start, 460 &ar934x_chip_device_stopped, 461 &ar934x_chip_set_pll_ge, 462 &ar934x_chip_set_mii_speed, 463 &ar934x_chip_set_mii_if, 464 &ar934x_chip_get_eth_pll, 465 &ar934x_chip_ddr_flush, 466 &ar934x_chip_init_usb_peripheral, 467 &ar934x_chip_reset_ethernet_switch, 468 &ar934x_chip_reset_wmac, 469 &ar934x_chip_init_gmac, 470 &ar934x_chip_reset_nfc, 471 &ar934x_chip_gpio_output_configure, 472}; 473