ar934x_chip.c revision 285121
1/*- 2 * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/mips/atheros/ar934x_chip.c 285121 2015-07-04 03:05:57Z adrian $"); 29 30#include "opt_ddb.h" 31 32#include <sys/param.h> 33#include <sys/conf.h> 34#include <sys/kernel.h> 35#include <sys/systm.h> 36#include <sys/bus.h> 37#include <sys/cons.h> 38#include <sys/kdb.h> 39#include <sys/reboot.h> 40 41#include <vm/vm.h> 42#include <vm/vm_page.h> 43 44#include <net/ethernet.h> 45 46#include <machine/clock.h> 47#include <machine/cpu.h> 48#include <machine/cpuregs.h> 49#include <machine/hwfunc.h> 50#include <machine/md_var.h> 51#include <machine/trap.h> 52#include <machine/vmparam.h> 53 54#include <mips/atheros/ar71xxreg.h> 55#include <mips/atheros/ar934xreg.h> 56 57#include <mips/atheros/ar71xx_cpudef.h> 58#include <mips/atheros/ar71xx_setup.h> 59 60#include <mips/atheros/ar71xx_chip.h> 61#include <mips/atheros/ar934x_chip.h> 62 63static void 64ar934x_chip_detect_mem_size(void) 65{ 66} 67 68static uint32_t 69ar934x_get_pll_freq(uint32_t ref, uint32_t ref_div, uint32_t nint, 70 uint32_t nfrac, uint32_t frac, uint32_t out_div) 71{ 72 uint64_t t; 73 uint32_t ret; 74 75 t = u_ar71xx_refclk; 76 t *= nint; 77 t = t / ref_div; 78 ret = t; 79 80 t = u_ar71xx_refclk; 81 t *= nfrac; 82 t = t / (ref_div * frac); 83 ret += t; 84 85 ret /= (1 << out_div); 86 return (ret); 87} 88 89static void 90ar934x_chip_detect_sys_frequency(void) 91{ 92 uint32_t pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 93 uint32_t cpu_pll, ddr_pll; 94 uint32_t bootstrap; 95 uint32_t reg; 96 97 bootstrap = ATH_READ_REG(AR934X_RESET_REG_BOOTSTRAP); 98 if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 99 u_ar71xx_refclk = 40 * 1000 * 1000; 100 else 101 u_ar71xx_refclk = 25 * 1000 * 1000; 102 103 pll = ATH_READ_REG(AR934X_SRIF_CPU_DPLL2_REG); 104 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 105 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 106 AR934X_SRIF_DPLL2_OUTDIV_MASK; 107 pll = ATH_READ_REG(AR934X_SRIF_CPU_DPLL1_REG); 108 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 109 AR934X_SRIF_DPLL1_NINT_MASK; 110 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 111 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 112 AR934X_SRIF_DPLL1_REFDIV_MASK; 113 frac = 1 << 18; 114 } else { 115 pll = ATH_READ_REG(AR934X_PLL_CPU_CONFIG_REG); 116 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 117 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 118 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 119 AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 120 nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 121 AR934X_PLL_CPU_CONFIG_NINT_MASK; 122 nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 123 AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 124 frac = 1 << 6; 125 } 126 127 cpu_pll = ar934x_get_pll_freq(u_ar71xx_refclk, ref_div, nint, 128 nfrac, frac, out_div); 129 130 pll = ATH_READ_REG(AR934X_SRIF_DDR_DPLL2_REG); 131 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 132 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 133 AR934X_SRIF_DPLL2_OUTDIV_MASK; 134 pll = ATH_READ_REG(AR934X_SRIF_DDR_DPLL1_REG); 135 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 136 AR934X_SRIF_DPLL1_NINT_MASK; 137 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 138 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 139 AR934X_SRIF_DPLL1_REFDIV_MASK; 140 frac = 1 << 18; 141 } else { 142 pll = ATH_READ_REG(AR934X_PLL_DDR_CONFIG_REG); 143 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 144 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 145 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 146 AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 147 nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 148 AR934X_PLL_DDR_CONFIG_NINT_MASK; 149 nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 150 AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 151 frac = 1 << 10; 152 } 153 154 ddr_pll = ar934x_get_pll_freq(u_ar71xx_refclk, ref_div, nint, 155 nfrac, frac, out_div); 156 157 clk_ctrl = ATH_READ_REG(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 158 159 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 160 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 161 162 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 163 u_ar71xx_cpu_freq = u_ar71xx_refclk; 164 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 165 u_ar71xx_cpu_freq = cpu_pll / (postdiv + 1); 166 else 167 u_ar71xx_cpu_freq = ddr_pll / (postdiv + 1); 168 169 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 170 AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 171 172 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 173 u_ar71xx_ddr_freq = u_ar71xx_refclk; 174 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 175 u_ar71xx_ddr_freq = ddr_pll / (postdiv + 1); 176 else 177 u_ar71xx_ddr_freq = cpu_pll / (postdiv + 1); 178 179 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 180 AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 181 182 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 183 u_ar71xx_ahb_freq = u_ar71xx_refclk; 184 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 185 u_ar71xx_ahb_freq = ddr_pll / (postdiv + 1); 186 else 187 u_ar71xx_ahb_freq = cpu_pll / (postdiv + 1); 188 189 u_ar71xx_wdt_freq = u_ar71xx_refclk; 190 u_ar71xx_uart_freq = u_ar71xx_refclk; 191 192 /* 193 * Next, fetch reference clock speed for MDIO bus. 194 */ 195 reg = ATH_READ_REG(AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); 196 if (reg & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) { 197 printf("%s: mdio=100MHz\n", __func__); 198 u_ar71xx_mdio_freq = (100 * 1000 * 1000); 199 } else { 200 printf("%s: mdio=%d Hz\n", __func__, u_ar71xx_refclk); 201 u_ar71xx_mdio_freq = u_ar71xx_refclk; 202 } 203} 204 205static void 206ar934x_chip_device_stop(uint32_t mask) 207{ 208 uint32_t reg; 209 210 reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE); 211 ATH_WRITE_REG(AR934X_RESET_REG_RESET_MODULE, reg | mask); 212} 213 214static void 215ar934x_chip_device_start(uint32_t mask) 216{ 217 uint32_t reg; 218 219 reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE); 220 ATH_WRITE_REG(AR934X_RESET_REG_RESET_MODULE, reg & ~mask); 221} 222 223static int 224ar934x_chip_device_stopped(uint32_t mask) 225{ 226 uint32_t reg; 227 228 reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE); 229 return ((reg & mask) == mask); 230} 231 232static void 233ar934x_chip_set_mii_speed(uint32_t unit, uint32_t speed) 234{ 235 236 /* XXX TODO */ 237 return; 238} 239 240/* 241 * XXX TODO !! 242 */ 243static void 244ar934x_chip_set_pll_ge(int unit, int speed, uint32_t pll) 245{ 246 247 switch (unit) { 248 case 0: 249 ATH_WRITE_REG(AR934X_PLL_ETH_XMII_CONTROL_REG, pll); 250 break; 251 case 1: 252 /* XXX nothing */ 253 break; 254 default: 255 printf("%s: invalid PLL set for arge unit: %d\n", 256 __func__, unit); 257 return; 258 } 259} 260 261static void 262ar934x_chip_ddr_flush(ar71xx_flush_ddr_id_t id) 263{ 264 265 switch (id) { 266 case AR71XX_CPU_DDR_FLUSH_GE0: 267 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_GE0); 268 break; 269 case AR71XX_CPU_DDR_FLUSH_GE1: 270 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_GE1); 271 break; 272 case AR71XX_CPU_DDR_FLUSH_USB: 273 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_USB); 274 break; 275 case AR71XX_CPU_DDR_FLUSH_PCIE: 276 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); 277 break; 278 case AR71XX_CPU_DDR_FLUSH_WMAC: 279 ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_WMAC); 280 break; 281 default: 282 printf("%s: invalid DDR flush id (%d)\n", __func__, id); 283 break; 284 } 285} 286 287 288static uint32_t 289ar934x_chip_get_eth_pll(unsigned int mac, int speed) 290{ 291 uint32_t pll; 292 293 switch (speed) { 294 case 10: 295 pll = AR934X_PLL_VAL_10; 296 break; 297 case 100: 298 pll = AR934X_PLL_VAL_100; 299 break; 300 case 1000: 301 pll = AR934X_PLL_VAL_1000; 302 break; 303 default: 304 printf("%s%d: invalid speed %d\n", __func__, mac, speed); 305 pll = 0; 306 } 307 return (pll); 308} 309 310static void 311ar934x_chip_reset_ethernet_switch(void) 312{ 313 314 ar71xx_device_stop(AR934X_RESET_ETH_SWITCH); 315 DELAY(100); 316 ar71xx_device_start(AR934X_RESET_ETH_SWITCH); 317 DELAY(100); 318} 319 320static void 321ar934x_configure_gmac(uint32_t gmac_cfg) 322{ 323 uint32_t reg; 324 325 reg = ATH_READ_REG(AR934X_GMAC_REG_ETH_CFG); 326 printf("%s: ETH_CFG=0x%08x\n", __func__, reg); 327 328 reg &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | 329 AR934X_ETH_CFG_MII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE | 330 AR934X_ETH_CFG_SW_PHY_SWAP); 331 332 reg |= gmac_cfg; 333 334 ATH_WRITE_REG(AR934X_GMAC_REG_ETH_CFG, reg); 335} 336 337static void 338ar934x_chip_init_usb_peripheral(void) 339{ 340 uint32_t reg; 341 342 reg = ATH_READ_REG(AR934X_RESET_REG_BOOTSTRAP); 343 if (reg & AR934X_BOOTSTRAP_USB_MODE_DEVICE) 344 return; 345 346 ar71xx_device_stop(AR934X_RESET_USBSUS_OVERRIDE); 347 DELAY(100); 348 349 ar71xx_device_start(AR934X_RESET_USB_PHY); 350 DELAY(100); 351 352 ar71xx_device_start(AR934X_RESET_USB_PHY_ANALOG); 353 DELAY(100); 354 355 ar71xx_device_start(AR934X_RESET_USB_HOST); 356 DELAY(100); 357} 358 359static void 360ar934x_chip_set_mii_if(uint32_t unit, uint32_t mii_mode) 361{ 362 363 /* 364 * XXX ! 365 * 366 * Nothing to see here; although gmac0 can have its 367 * MII configuration changed, the register values 368 * are slightly different. 369 */ 370} 371 372/* 373 * XXX TODO: fetch default MII divider configuration 374 */ 375 376static void 377ar934x_chip_reset_wmac(void) 378{ 379 380 /* XXX TODO */ 381} 382 383static void 384ar934x_chip_init_gmac(void) 385{ 386 long gmac_cfg; 387 388 if (resource_long_value("ar934x_gmac", 0, "gmac_cfg", 389 &gmac_cfg) == 0) { 390 printf("%s: gmac_cfg=0x%08lx\n", 391 __func__, 392 (long) gmac_cfg); 393 ar934x_configure_gmac((uint32_t) gmac_cfg); 394 } 395} 396 397/* 398 * Reset the NAND Flash Controller. 399 * 400 * + active=1 means "make it active". 401 * + active=0 means "make it inactive". 402 */ 403static void 404ar934x_chip_reset_nfc(int active) 405{ 406 407 if (active) { 408 ar71xx_device_start(AR934X_RESET_NANDF); 409 DELAY(100); 410 411 ar71xx_device_start(AR934X_RESET_ETH_SWITCH_ANALOG); 412 DELAY(250); 413 } else { 414 ar71xx_device_stop(AR934X_RESET_ETH_SWITCH_ANALOG); 415 DELAY(250); 416 417 ar71xx_device_stop(AR934X_RESET_NANDF); 418 DELAY(100); 419 } 420} 421 422/* 423 * Configure the GPIO output mux setup. 424 * 425 * The AR934x introduced an output mux which allowed 426 * certain functions to be configured on any pin. 427 * Specifically, the switch PHY link LEDs and 428 * WMAC external RX LNA switches are not limited to 429 * a specific GPIO pin. 430 */ 431static void 432ar934x_chip_gpio_output_configure(int gpio, uint8_t func) 433{ 434 uint32_t reg, s; 435 uint32_t t; 436 437 if (gpio > AR934X_GPIO_COUNT) 438 return; 439 440 reg = AR934X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4); 441 s = 8 * (gpio % 4); 442 443 /* read-modify-write */ 444 t = ATH_READ_REG(AR71XX_GPIO_BASE + reg); 445 t &= ~(0xff << s); 446 t |= func << s; 447 ATH_WRITE_REG(AR71XX_GPIO_BASE + reg, t); 448 449 /* flush write */ 450 ATH_READ_REG(AR71XX_GPIO_BASE + reg); 451} 452 453struct ar71xx_cpu_def ar934x_chip_def = { 454 &ar934x_chip_detect_mem_size, 455 &ar934x_chip_detect_sys_frequency, 456 &ar934x_chip_device_stop, 457 &ar934x_chip_device_start, 458 &ar934x_chip_device_stopped, 459 &ar934x_chip_set_pll_ge, 460 &ar934x_chip_set_mii_speed, 461 &ar934x_chip_set_mii_if, 462 &ar934x_chip_get_eth_pll, 463 &ar934x_chip_ddr_flush, 464 &ar934x_chip_init_usb_peripheral, 465 &ar934x_chip_reset_ethernet_switch, 466 &ar934x_chip_reset_wmac, 467 &ar934x_chip_init_gmac, 468 &ar934x_chip_reset_nfc, 469 &ar934x_chip_gpio_output_configure, 470}; 471