ar933x_chip.c revision 248809
1248782Sadrian/*- 2248782Sadrian * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org> 3248782Sadrian * All rights reserved. 4248782Sadrian * 5248782Sadrian * Redistribution and use in source and binary forms, with or without 6248782Sadrian * modification, are permitted provided that the following conditions 7248782Sadrian * are met: 8248782Sadrian * 1. Redistributions of source code must retain the above copyright 9248782Sadrian * notice, this list of conditions and the following disclaimer. 10248782Sadrian * 2. Redistributions in binary form must reproduce the above copyright 11248782Sadrian * notice, this list of conditions and the following disclaimer in the 12248782Sadrian * documentation and/or other materials provided with the distribution. 13248782Sadrian * 14248782Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15248782Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16248782Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17248782Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18248782Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19248782Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20248782Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21248782Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22248782Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23248782Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24248782Sadrian * SUCH DAMAGE. 25248782Sadrian */ 26248782Sadrian 27248782Sadrian#include <sys/cdefs.h> 28248782Sadrian__FBSDID("$FreeBSD: head/sys/mips/atheros/ar933x_chip.c 248809 2013-03-28 05:43:03Z adrian $"); 29248782Sadrian 30248782Sadrian#include "opt_ddb.h" 31248782Sadrian 32248782Sadrian#include <sys/param.h> 33248782Sadrian#include <sys/conf.h> 34248782Sadrian#include <sys/kernel.h> 35248782Sadrian#include <sys/systm.h> 36248782Sadrian#include <sys/bus.h> 37248782Sadrian#include <sys/cons.h> 38248782Sadrian#include <sys/kdb.h> 39248782Sadrian#include <sys/reboot.h> 40248782Sadrian 41248782Sadrian#include <vm/vm.h> 42248782Sadrian#include <vm/vm_page.h> 43248782Sadrian 44248782Sadrian#include <net/ethernet.h> 45248782Sadrian 46248782Sadrian#include <machine/clock.h> 47248782Sadrian#include <machine/cpu.h> 48248782Sadrian#include <machine/cpuregs.h> 49248782Sadrian#include <machine/hwfunc.h> 50248782Sadrian#include <machine/md_var.h> 51248782Sadrian#include <machine/trap.h> 52248782Sadrian#include <machine/vmparam.h> 53248782Sadrian 54248782Sadrian#include <mips/atheros/ar71xxreg.h> 55248782Sadrian#include <mips/atheros/ar933xreg.h> 56248782Sadrian 57248782Sadrian#include <mips/atheros/ar71xx_cpudef.h> 58248782Sadrian#include <mips/atheros/ar71xx_setup.h> 59248782Sadrian 60248782Sadrian#include <mips/atheros/ar71xx_chip.h> 61248782Sadrian#include <mips/atheros/ar933x_chip.h> 62248782Sadrian 63248782Sadrianstatic void 64248782Sadrianar933x_chip_detect_mem_size(void) 65248782Sadrian{ 66248782Sadrian} 67248782Sadrian 68248782Sadrianstatic void 69248782Sadrianar933x_chip_detect_sys_frequency(void) 70248782Sadrian{ 71248782Sadrian uint32_t clock_ctrl; 72248782Sadrian uint32_t cpu_config; 73248782Sadrian uint32_t freq; 74248782Sadrian uint32_t t; 75248782Sadrian 76248782Sadrian t = ATH_READ_REG(AR933X_RESET_REG_BOOTSTRAP); 77248782Sadrian if (t & AR933X_BOOTSTRAP_REF_CLK_40) 78248782Sadrian u_ar71xx_refclk = (40 * 1000 * 1000); 79248782Sadrian else 80248782Sadrian u_ar71xx_refclk = (25 * 1000 * 1000); 81248782Sadrian 82248782Sadrian clock_ctrl = ATH_READ_REG(AR933X_PLL_CLOCK_CTRL_REG); 83248782Sadrian if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 84248782Sadrian u_ar71xx_cpu_freq = u_ar71xx_refclk; 85248782Sadrian u_ar71xx_ahb_freq = u_ar71xx_refclk; 86248782Sadrian u_ar71xx_ddr_freq = u_ar71xx_refclk; 87248782Sadrian } else { 88248782Sadrian cpu_config = ATH_READ_REG(AR933X_PLL_CPU_CONFIG_REG); 89248782Sadrian 90248782Sadrian t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 91248782Sadrian AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 92248782Sadrian freq = u_ar71xx_refclk / t; 93248782Sadrian 94248782Sadrian t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 95248782Sadrian AR933X_PLL_CPU_CONFIG_NINT_MASK; 96248782Sadrian freq *= t; 97248782Sadrian 98248782Sadrian t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 99248782Sadrian AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 100248782Sadrian if (t == 0) 101248782Sadrian t = 1; 102248782Sadrian 103248782Sadrian freq >>= t; 104248782Sadrian 105248782Sadrian t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 106248782Sadrian AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 107248782Sadrian u_ar71xx_cpu_freq = freq / t; 108248782Sadrian 109248782Sadrian t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 110248782Sadrian AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 111248782Sadrian u_ar71xx_ddr_freq = freq / t; 112248782Sadrian 113248782Sadrian t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 114248782Sadrian AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 115248782Sadrian u_ar71xx_ahb_freq = freq / t; 116248782Sadrian } 117248782Sadrian} 118248782Sadrian 119248782Sadrianstatic void 120248782Sadrianar933x_chip_device_stop(uint32_t mask) 121248782Sadrian{ 122248809Sadrian uint32_t reg; 123248782Sadrian 124248782Sadrian reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE); 125248809Sadrian ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg | mask); 126248782Sadrian} 127248782Sadrian 128248782Sadrianstatic void 129248782Sadrianar933x_chip_device_start(uint32_t mask) 130248782Sadrian{ 131248809Sadrian uint32_t reg; 132248782Sadrian 133248782Sadrian reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE); 134248809Sadrian ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg & ~mask); 135248782Sadrian} 136248782Sadrian 137248782Sadrianstatic int 138248782Sadrianar933x_chip_device_stopped(uint32_t mask) 139248782Sadrian{ 140248782Sadrian uint32_t reg; 141248782Sadrian 142248782Sadrian reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE); 143248782Sadrian return ((reg & mask) == mask); 144248782Sadrian} 145248782Sadrian 146248782Sadrianstatic void 147248782Sadrianar933x_chip_set_mii_speed(uint32_t unit, uint32_t speed) 148248782Sadrian{ 149248782Sadrian 150248782Sadrian /* XXX TODO */ 151248782Sadrian return; 152248782Sadrian} 153248782Sadrian 154248782Sadrian/* 155248782Sadrian * XXX TODO !! 156248782Sadrian */ 157248782Sadrianstatic void 158248782Sadrianar933x_chip_set_pll_ge(int unit, int speed, uint32_t pll) 159248782Sadrian{ 160248782Sadrian 161248782Sadrian switch (unit) { 162248782Sadrian case 0: 163248782Sadrian /* XXX TODO */ 164248782Sadrian break; 165248782Sadrian case 1: 166248782Sadrian /* XXX TODO */ 167248782Sadrian break; 168248782Sadrian default: 169248782Sadrian printf("%s: invalid PLL set for arge unit: %d\n", 170248782Sadrian __func__, unit); 171248782Sadrian return; 172248782Sadrian } 173248782Sadrian} 174248782Sadrian 175248782Sadrianstatic void 176248782Sadrianar933x_chip_ddr_flush_ge(int unit) 177248782Sadrian{ 178248782Sadrian 179248782Sadrian switch (unit) { 180248782Sadrian case 0: 181248782Sadrian ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0); 182248782Sadrian break; 183248782Sadrian case 1: 184248782Sadrian ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1); 185248782Sadrian break; 186248782Sadrian default: 187248782Sadrian printf("%s: invalid DDR flush for arge unit: %d\n", 188248782Sadrian __func__, unit); 189248782Sadrian return; 190248782Sadrian } 191248782Sadrian} 192248782Sadrian 193248782Sadrianstatic void 194248782Sadrianar933x_chip_ddr_flush_ip2(void) 195248782Sadrian{ 196248782Sadrian 197248782Sadrian ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC); 198248782Sadrian} 199248782Sadrian 200248782Sadrianstatic uint32_t 201248782Sadrianar933x_chip_get_eth_pll(unsigned int mac, int speed) 202248782Sadrian{ 203248782Sadrian 204248782Sadrian return (0); 205248782Sadrian} 206248782Sadrian 207248782Sadrianstatic void 208248782Sadrianar933x_chip_init_usb_peripheral(void) 209248782Sadrian{ 210248782Sadrian#if 0 211248782Sadrian switch (ar71xx_soc) { 212248782Sadrian case AR71XX_SOC_AR7240: 213248782Sadrian ar71xx_device_stop(AR724X_RESET_MODULE_USB_OHCI_DLL | 214248782Sadrian AR724X_RESET_USB_HOST); 215248782Sadrian DELAY(1000); 216248782Sadrian 217248782Sadrian ar71xx_device_start(AR724X_RESET_MODULE_USB_OHCI_DLL | 218248782Sadrian AR724X_RESET_USB_HOST); 219248782Sadrian DELAY(1000); 220248782Sadrian 221248782Sadrian /* 222248782Sadrian * WAR for HW bug. Here it adjusts the duration 223248782Sadrian * between two SOFS. 224248782Sadrian */ 225248782Sadrian ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ, 226248782Sadrian (3 << USB_CTRL_FLADJ_A0_SHIFT)); 227248782Sadrian 228248782Sadrian break; 229248782Sadrian 230248782Sadrian case AR71XX_SOC_AR7241: 231248782Sadrian case AR71XX_SOC_AR7242: 232248782Sadrian ar71xx_device_start(AR724X_RESET_MODULE_USB_OHCI_DLL); 233248782Sadrian DELAY(100); 234248782Sadrian 235248782Sadrian ar71xx_device_start(AR724X_RESET_USB_HOST); 236248782Sadrian DELAY(100); 237248782Sadrian 238248782Sadrian ar71xx_device_start(AR724X_RESET_USB_PHY); 239248782Sadrian DELAY(100); 240248782Sadrian 241248782Sadrian break; 242248782Sadrian 243248782Sadrian default: 244248782Sadrian break; 245248782Sadrian } 246248782Sadrian#endif 247248782Sadrian} 248248782Sadrian 249248782Sadrianstruct ar71xx_cpu_def ar933x_chip_def = { 250248782Sadrian &ar933x_chip_detect_mem_size, 251248782Sadrian &ar933x_chip_detect_sys_frequency, 252248782Sadrian &ar933x_chip_device_stop, 253248782Sadrian &ar933x_chip_device_start, 254248782Sadrian &ar933x_chip_device_stopped, 255248782Sadrian &ar933x_chip_set_pll_ge, 256248782Sadrian &ar933x_chip_set_mii_speed, 257248782Sadrian &ar71xx_chip_set_mii_if, 258248782Sadrian &ar933x_chip_ddr_flush_ge, 259248782Sadrian &ar933x_chip_get_eth_pll, 260248782Sadrian &ar933x_chip_ddr_flush_ip2, 261248782Sadrian &ar933x_chip_init_usb_peripheral 262248782Sadrian}; 263