ar71xx_chip.c revision 228450
12061Sjkh/*- 225980Sasami * Copyright (c) 2010 Adrian Chadd 32061Sjkh * All rights reserved. 42061Sjkh * 515603Smarkm * Redistribution and use in source and binary forms, with or without 63197Scsgr * modification, are permitted provided that the following conditions 720710Sasami * are met: 820710Sasami * 1. Redistributions of source code must retain the above copyright 93197Scsgr * notice, this list of conditions and the following disclaimer. 102061Sjkh * 2. Redistributions in binary form must reproduce the above copyright 1112483Speter * notice, this list of conditions and the following disclaimer in the 122160Scsgr * documentation and/or other materials provided with the distribution. 132834Swollman * 142061Sjkh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 152061Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 162160Scsgr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1717308Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1819320Sadam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1921536Sjmacd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2025399Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2125980Sasami * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221594Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2317308Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2417308Speter * SUCH DAMAGE. 2517308Speter */ 2617308Speter 2717308Speter#include <sys/cdefs.h> 2817308Speter__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_chip.c 228450 2011-12-13 05:13:51Z adrian $"); 2917308Speter 3019175Sbde#include "opt_ddb.h" 3119175Sbde 3219175Sbde#include <sys/param.h> 3319175Sbde#include <sys/conf.h> 3417308Speter#include <sys/kernel.h> 3525647Sbde#include <sys/systm.h> 3617308Speter#include <sys/bus.h> 372061Sjkh#include <sys/cons.h> 382061Sjkh#include <sys/kdb.h> 391594Srgrimes#include <sys/reboot.h> 4025313Sbde 4125313Sbde#include <vm/vm.h> 4225313Sbde#include <vm/vm_page.h> 4325313Sbde 4425313Sbde#include <net/ethernet.h> 4525313Sbde 4625313Sbde#include <machine/clock.h> 4725313Sbde#include <machine/cpu.h> 487407Srgrimes#include <machine/cpuregs.h> 497108Sphk#include <machine/hwfunc.h> 507108Sphk#include <machine/md_var.h> 517108Sphk#include <machine/trap.h> 527407Srgrimes#include <machine/vmparam.h> 537407Srgrimes 547407Srgrimes#include <mips/atheros/ar71xxreg.h> 557108Sphk#include <mips/atheros/ar71xx_chip.h> 562061Sjkh#include <mips/atheros/ar71xx_cpudef.h> 572061Sjkh 582061Sjkh#include <mips/sentry5/s5reg.h> 5917308Speter 602061Sjkh/* XXX these should replace the current definitions in ar71xxreg.h */ 612061Sjkh/* XXX perhaps an ar71xx_chip.h header file? */ 622061Sjkh#define AR71XX_PLL_REG_CPU_CONFIG AR71XX_PLL_CPU_BASE + 0x00 632061Sjkh#define AR71XX_PLL_REG_SEC_CONFIG AR71XX_PLL_CPU_BASE + 0x04 642061Sjkh#define AR71XX_PLL_REG_ETH0_INT_CLOCK AR71XX_PLL_CPU_BASE + 0x10 653197Scsgr#define AR71XX_PLL_REG_ETH1_INT_CLOCK AR71XX_PLL_CPU_BASE + 0x14 662626Scsgr 672626Scsgr#define AR71XX_PLL_DIV_SHIFT 3 682061Sjkh#define AR71XX_PLL_DIV_MASK 0x1f 692061Sjkh#define AR71XX_CPU_DIV_SHIFT 16 702061Sjkh#define AR71XX_CPU_DIV_MASK 0x3 712061Sjkh#define AR71XX_DDR_DIV_SHIFT 18 722061Sjkh#define AR71XX_DDR_DIV_MASK 0x3 732061Sjkh#define AR71XX_AHB_DIV_SHIFT 20 7419320Sadam#define AR71XX_AHB_DIV_MASK 0x7 752061Sjkh 762061Sjkh/* XXX these shouldn't be in here - this file is a per-chip file */ 772061Sjkh/* XXX these should be in the top-level ar71xx type, not ar71xx -chip */ 782061Sjkhuint32_t u_ar71xx_cpu_freq; 792061Sjkhuint32_t u_ar71xx_ahb_freq; 802061Sjkhuint32_t u_ar71xx_ddr_freq; 812061Sjkh 822061Sjkhstatic void 832061Sjkhar71xx_chip_detect_mem_size(void) 842061Sjkh{ 852061Sjkh} 862834Swollman 872834Swollmanstatic void 882834Swollmanar71xx_chip_detect_sys_frequency(void) 892834Swollman{ 902834Swollman uint32_t pll; 912834Swollman uint32_t freq; 921594Srgrimes uint32_t div; 934486Sphk 944486Sphk pll = ATH_READ_REG(AR71XX_PLL_REG_CPU_CONFIG); 954486Sphk 964486Sphk div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; 974486Sphk freq = div * AR71XX_BASE_FREQ; 982061Sjkh 992061Sjkh div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; 10025979Sjkh u_ar71xx_cpu_freq = freq / div; 10125979Sjkh 10225979Sjkh div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; 10325979Sjkh u_ar71xx_ddr_freq = freq / div; 1042061Sjkh 10525979Sjkh div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 1062061Sjkh u_ar71xx_ahb_freq = u_ar71xx_cpu_freq / div; 1072061Sjkh} 10817308Speter 1092061Sjkh/* 1102061Sjkh * This does not lock the CPU whilst doing the work! 1112061Sjkh */ 1122061Sjkhstatic void 1132061Sjkhar71xx_chip_device_stop(uint32_t mask) 11412483Speter{ 11512483Speter uint32_t reg; 11612483Speter 11712483Speter reg = ATH_READ_REG(AR71XX_RST_RESET); 1182061Sjkh ATH_WRITE_REG(AR71XX_RST_RESET, reg | mask); 1192061Sjkh} 1208854Srgrimes 1212061Sjkhstatic void 1222061Sjkhar71xx_chip_device_start(uint32_t mask) 12312483Speter{ 1242061Sjkh uint32_t reg; 12518714Sache 12618714Sache reg = ATH_READ_REG(AR71XX_RST_RESET); 12718714Sache ATH_WRITE_REG(AR71XX_RST_RESET, reg & ~mask); 12817308Speter} 12917308Speter 13017308Speterstatic int 13117308Speterar71xx_chip_device_stopped(uint32_t mask) 13221536Sjmacd{ 13315603Smarkm uint32_t reg; 13417308Speter 13517308Speter reg = ATH_READ_REG(AR71XX_RST_RESET); 13617308Speter return ((reg & mask) == mask); 13717308Speter} 13817308Speter 13917308Speter/* Speed is either 10, 100 or 1000 */ 14017308Speterstatic void 14117308Speterar71xx_chip_set_pll_ge(int unit, int speed) 14217308Speter{ 14318362Sjkh uint32_t pll; 14419966Sache 14518362Sjkh switch (speed) { 14617308Speter case 10: 14717308Speter pll = PLL_ETH_INT_CLK_10; 14817308Speter break; 14917308Speter case 100: 15017308Speter pll = PLL_ETH_INT_CLK_100; 15117308Speter break; 15216550Sjkh case 1000: 1532061Sjkh pll = PLL_ETH_INT_CLK_1000; 15417308Speter break; 1552061Sjkh default: 15617308Speter printf("%s%d: invalid speed %d\n", 1572061Sjkh __func__, unit, speed); 15817308Speter return; 15917308Speter } 16017308Speter switch (unit) { 16117308Speter case 0: 16217308Speter ar71xx_write_pll(AR71XX_PLL_SEC_CONFIG, 16317308Speter AR71XX_PLL_ETH_INT0_CLK, pll, 16417466Speter AR71XX_PLL_ETH0_SHIFT); 16517308Speter break; 16617308Speter case 1: 16717466Speter ar71xx_write_pll(AR71XX_PLL_SEC_CONFIG, 16817308Speter AR71XX_PLL_ETH_INT1_CLK, pll, 16917308Speter AR71XX_PLL_ETH1_SHIFT); 17017308Speter break; 17117308Speter default: 17217466Speter printf("%s: invalid PLL set for arge unit: %d\n", 17317308Speter __func__, unit); 17417308Speter return; 17517308Speter } 17617308Speter} 17717308Speter 17817308Speterstatic void 17917308Speterar71xx_chip_ddr_flush_ge(int unit) 18017308Speter{ 18117308Speter 18217308Speter switch (unit) { 18317308Speter case 0: 18417308Speter ar71xx_ddr_flush(AR71XX_WB_FLUSH_GE0); 18517308Speter break; 18617308Speter case 1: 18717308Speter ar71xx_ddr_flush(AR71XX_WB_FLUSH_GE1); 18817308Speter break; 18917308Speter default: 19017308Speter printf("%s: invalid DDR flush for arge unit: %d\n", 19117308Speter __func__, unit); 19217308Speter return; 19317308Speter } 19417308Speter} 19517308Speter 19617308Speterstatic void 19717308Speterar71xx_chip_ddr_flush_ip2(void) 19817308Speter{ 19917308Speter ar71xx_ddr_flush(AR71XX_WB_FLUSH_PCI); 20018392Speter} 20117308Speter 20217308Speterstatic uint32_t 20317308Speterar71xx_chip_get_eth_pll(unsigned int mac, int speed) 20417308Speter{ 20517962Speter return 0; 20617308Speter} 20717962Speter 20817962Speterstatic void 20917962Speterar71xx_chip_init_usb_peripheral(void) 21017962Speter{ 21117962Speter 21217962Speter ar71xx_device_stop(RST_RESET_USB_OHCI_DLL | 21317962Speter RST_RESET_USB_HOST | RST_RESET_USB_PHY); 21417962Speter DELAY(1000); 21517962Speter 21617962Speter ar71xx_device_start(RST_RESET_USB_OHCI_DLL | 21717962Speter RST_RESET_USB_HOST | RST_RESET_USB_PHY); 21817962Speter DELAY(1000); 21917962Speter 22017962Speter ATH_WRITE_REG(AR71XX_USB_CTRL_CONFIG, 22117962Speter USB_CTRL_CONFIG_OHCI_DES_SWAP | 22217308Speter USB_CTRL_CONFIG_OHCI_BUF_SWAP | 22316550Sjkh USB_CTRL_CONFIG_EHCI_DES_SWAP | 22417308Speter USB_CTRL_CONFIG_EHCI_BUF_SWAP); 22517308Speter 22617308Speter ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ, 22717308Speter (32 << USB_CTRL_FLADJ_HOST_SHIFT) | 22816550Sjkh (3 << USB_CTRL_FLADJ_A5_SHIFT)); 22916550Sjkh 23017308Speter DELAY(1000); 23117308Speter} 23219966Sache 23317962Speterstruct ar71xx_cpu_def ar71xx_chip_def = { 2342061Sjkh &ar71xx_chip_detect_mem_size, 23517308Speter &ar71xx_chip_detect_sys_frequency, 23617308Speter &ar71xx_chip_device_stop, 23717308Speter &ar71xx_chip_device_start, 23817308Speter &ar71xx_chip_device_stopped, 23917308Speter &ar71xx_chip_set_pll_ge, 24017308Speter &ar71xx_chip_ddr_flush_ge, 24117308Speter &ar71xx_chip_get_eth_pll, 24217308Speter &ar71xx_chip_ddr_flush_ip2, 24312483Speter &ar71xx_chip_init_usb_peripheral, 24417308Speter}; 24512483Speter