1d4a67d9dSGabor Juhos /* 2d4a67d9dSGabor Juhos * Atheros AR71XX/AR724X/AR913X specific setup 3d4a67d9dSGabor Juhos * 4d4a67d9dSGabor Juhos * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 5d4a67d9dSGabor Juhos * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6d4a67d9dSGabor Juhos * 7d4a67d9dSGabor Juhos * Parts of this file are based on Atheros' 2.6.15 BSP 8d4a67d9dSGabor Juhos * 9d4a67d9dSGabor Juhos * This program is free software; you can redistribute it and/or modify it 10d4a67d9dSGabor Juhos * under the terms of the GNU General Public License version 2 as published 11d4a67d9dSGabor Juhos * by the Free Software Foundation. 12d4a67d9dSGabor Juhos */ 13d4a67d9dSGabor Juhos 14d4a67d9dSGabor Juhos #include <linux/kernel.h> 15d4a67d9dSGabor Juhos #include <linux/init.h> 16d4a67d9dSGabor Juhos #include <linux/bootmem.h> 17d4a67d9dSGabor Juhos #include <linux/err.h> 18d4a67d9dSGabor Juhos #include <linux/clk.h> 19d4a67d9dSGabor Juhos 20d4a67d9dSGabor Juhos #include <asm/bootinfo.h> 21d4a67d9dSGabor Juhos #include <asm/time.h> /* for mips_hpt_frequency */ 22d4a67d9dSGabor Juhos #include <asm/reboot.h> /* for _machine_{restart,halt} */ 230aabf1a4SGabor Juhos #include <asm/mips_machine.h> 24d4a67d9dSGabor Juhos 25d4a67d9dSGabor Juhos #include <asm/mach-ath79/ath79.h> 26d4a67d9dSGabor Juhos #include <asm/mach-ath79/ar71xx_regs.h> 27d4a67d9dSGabor Juhos #include "common.h" 28d4a67d9dSGabor Juhos #include "dev-common.h" 290aabf1a4SGabor Juhos #include "machtypes.h" 30d4a67d9dSGabor Juhos 31d4a67d9dSGabor Juhos #define ATH79_SYS_TYPE_LEN 64 32d4a67d9dSGabor Juhos 33d4a67d9dSGabor Juhos #define AR71XX_BASE_FREQ 40000000 34d4a67d9dSGabor Juhos #define AR724X_BASE_FREQ 5000000 35d4a67d9dSGabor Juhos #define AR913X_BASE_FREQ 5000000 36d4a67d9dSGabor Juhos 37d4a67d9dSGabor Juhos static char ath79_sys_type[ATH79_SYS_TYPE_LEN]; 38d4a67d9dSGabor Juhos 39d4a67d9dSGabor Juhos static void ath79_restart(char *command) 40d4a67d9dSGabor Juhos { 41d4a67d9dSGabor Juhos ath79_device_reset_set(AR71XX_RESET_FULL_CHIP); 42d4a67d9dSGabor Juhos for (;;) 43d4a67d9dSGabor Juhos if (cpu_wait) 44d4a67d9dSGabor Juhos cpu_wait(); 45d4a67d9dSGabor Juhos } 46d4a67d9dSGabor Juhos 47d4a67d9dSGabor Juhos static void ath79_halt(void) 48d4a67d9dSGabor Juhos { 49d4a67d9dSGabor Juhos while (1) 50d4a67d9dSGabor Juhos cpu_wait(); 51d4a67d9dSGabor Juhos } 52d4a67d9dSGabor Juhos 53d4a67d9dSGabor Juhos static void __init ath79_detect_mem_size(void) 54d4a67d9dSGabor Juhos { 55d4a67d9dSGabor Juhos unsigned long size; 56d4a67d9dSGabor Juhos 57d4a67d9dSGabor Juhos for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX; 58d4a67d9dSGabor Juhos size <<= 1) { 59d4a67d9dSGabor Juhos if (!memcmp(ath79_detect_mem_size, 60d4a67d9dSGabor Juhos ath79_detect_mem_size + size, 1024)) 61d4a67d9dSGabor Juhos break; 62d4a67d9dSGabor Juhos } 63d4a67d9dSGabor Juhos 64d4a67d9dSGabor Juhos add_memory_region(0, size, BOOT_MEM_RAM); 65d4a67d9dSGabor Juhos } 66d4a67d9dSGabor Juhos 67d4a67d9dSGabor Juhos static void __init ath79_detect_sys_type(void) 68d4a67d9dSGabor Juhos { 69d4a67d9dSGabor Juhos char *chip = "????"; 70d4a67d9dSGabor Juhos u32 id; 71d4a67d9dSGabor Juhos u32 major; 72d4a67d9dSGabor Juhos u32 minor; 73d4a67d9dSGabor Juhos u32 rev = 0; 74d4a67d9dSGabor Juhos 75d4a67d9dSGabor Juhos id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID); 76d4a67d9dSGabor Juhos major = id & REV_ID_MAJOR_MASK; 77d4a67d9dSGabor Juhos 78d4a67d9dSGabor Juhos switch (major) { 79d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR71XX: 80d4a67d9dSGabor Juhos minor = id & AR71XX_REV_ID_MINOR_MASK; 81d4a67d9dSGabor Juhos rev = id >> AR71XX_REV_ID_REVISION_SHIFT; 82d4a67d9dSGabor Juhos rev &= AR71XX_REV_ID_REVISION_MASK; 83d4a67d9dSGabor Juhos switch (minor) { 84d4a67d9dSGabor Juhos case AR71XX_REV_ID_MINOR_AR7130: 85d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7130; 86d4a67d9dSGabor Juhos chip = "7130"; 87d4a67d9dSGabor Juhos break; 88d4a67d9dSGabor Juhos 89d4a67d9dSGabor Juhos case AR71XX_REV_ID_MINOR_AR7141: 90d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7141; 91d4a67d9dSGabor Juhos chip = "7141"; 92d4a67d9dSGabor Juhos break; 93d4a67d9dSGabor Juhos 94d4a67d9dSGabor Juhos case AR71XX_REV_ID_MINOR_AR7161: 95d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7161; 96d4a67d9dSGabor Juhos chip = "7161"; 97d4a67d9dSGabor Juhos break; 98d4a67d9dSGabor Juhos } 99d4a67d9dSGabor Juhos break; 100d4a67d9dSGabor Juhos 101d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR7240: 102d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7240; 103d4a67d9dSGabor Juhos chip = "7240"; 1048bed1288SGabor Juhos rev = id & AR724X_REV_ID_REVISION_MASK; 105d4a67d9dSGabor Juhos break; 106d4a67d9dSGabor Juhos 107d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR7241: 108d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7241; 109d4a67d9dSGabor Juhos chip = "7241"; 1108bed1288SGabor Juhos rev = id & AR724X_REV_ID_REVISION_MASK; 111d4a67d9dSGabor Juhos break; 112d4a67d9dSGabor Juhos 113d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR7242: 114d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7242; 115d4a67d9dSGabor Juhos chip = "7242"; 1168bed1288SGabor Juhos rev = id & AR724X_REV_ID_REVISION_MASK; 117d4a67d9dSGabor Juhos break; 118d4a67d9dSGabor Juhos 1196d1c8fdeSGabor Juhos case REV_ID_MAJOR_AR9330: 1206d1c8fdeSGabor Juhos ath79_soc = ATH79_SOC_AR9330; 1216d1c8fdeSGabor Juhos chip = "9330"; 1226d1c8fdeSGabor Juhos rev = id & AR933X_REV_ID_REVISION_MASK; 1236d1c8fdeSGabor Juhos break; 1246d1c8fdeSGabor Juhos 1256d1c8fdeSGabor Juhos case REV_ID_MAJOR_AR9331: 1266d1c8fdeSGabor Juhos ath79_soc = ATH79_SOC_AR9331; 1276d1c8fdeSGabor Juhos chip = "9331"; 1286d1c8fdeSGabor Juhos rev = id & AR933X_REV_ID_REVISION_MASK; 1296d1c8fdeSGabor Juhos break; 1306d1c8fdeSGabor Juhos 131d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR913X: 132d4a67d9dSGabor Juhos minor = id & AR913X_REV_ID_MINOR_MASK; 133d4a67d9dSGabor Juhos rev = id >> AR913X_REV_ID_REVISION_SHIFT; 134d4a67d9dSGabor Juhos rev &= AR913X_REV_ID_REVISION_MASK; 135d4a67d9dSGabor Juhos switch (minor) { 136d4a67d9dSGabor Juhos case AR913X_REV_ID_MINOR_AR9130: 137d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR9130; 138d4a67d9dSGabor Juhos chip = "9130"; 139d4a67d9dSGabor Juhos break; 140d4a67d9dSGabor Juhos 141d4a67d9dSGabor Juhos case AR913X_REV_ID_MINOR_AR9132: 142d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR9132; 143d4a67d9dSGabor Juhos chip = "9132"; 144d4a67d9dSGabor Juhos break; 145d4a67d9dSGabor Juhos } 146d4a67d9dSGabor Juhos break; 147d4a67d9dSGabor Juhos 148d4a67d9dSGabor Juhos default: 149d4a67d9dSGabor Juhos panic("ath79: unknown SoC, id:0x%08x\n", id); 150d4a67d9dSGabor Juhos } 151d4a67d9dSGabor Juhos 152*be5f3623SGabor Juhos ath79_soc_rev = rev; 153*be5f3623SGabor Juhos 154d4a67d9dSGabor Juhos sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); 155d4a67d9dSGabor Juhos pr_info("SoC: %s\n", ath79_sys_type); 156d4a67d9dSGabor Juhos } 157d4a67d9dSGabor Juhos 158d4a67d9dSGabor Juhos const char *get_system_type(void) 159d4a67d9dSGabor Juhos { 160d4a67d9dSGabor Juhos return ath79_sys_type; 161d4a67d9dSGabor Juhos } 162d4a67d9dSGabor Juhos 163d4a67d9dSGabor Juhos unsigned int __cpuinit get_c0_compare_int(void) 164d4a67d9dSGabor Juhos { 165d4a67d9dSGabor Juhos return CP0_LEGACY_COMPARE_IRQ; 166d4a67d9dSGabor Juhos } 167d4a67d9dSGabor Juhos 168d4a67d9dSGabor Juhos void __init plat_mem_setup(void) 169d4a67d9dSGabor Juhos { 170d4a67d9dSGabor Juhos set_io_port_base(KSEG1); 171d4a67d9dSGabor Juhos 172d4a67d9dSGabor Juhos ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, 173d4a67d9dSGabor Juhos AR71XX_RESET_SIZE); 174d4a67d9dSGabor Juhos ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, 175d4a67d9dSGabor Juhos AR71XX_PLL_SIZE); 176d4a67d9dSGabor Juhos ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, 177d4a67d9dSGabor Juhos AR71XX_DDR_CTRL_SIZE); 178d4a67d9dSGabor Juhos 179d4a67d9dSGabor Juhos ath79_detect_sys_type(); 180d4a67d9dSGabor Juhos ath79_detect_mem_size(); 181d4a67d9dSGabor Juhos ath79_clocks_init(); 182d4a67d9dSGabor Juhos 183d4a67d9dSGabor Juhos _machine_restart = ath79_restart; 184d4a67d9dSGabor Juhos _machine_halt = ath79_halt; 185d4a67d9dSGabor Juhos pm_power_off = ath79_halt; 186d4a67d9dSGabor Juhos } 187d4a67d9dSGabor Juhos 188d4a67d9dSGabor Juhos void __init plat_time_init(void) 189d4a67d9dSGabor Juhos { 190d4a67d9dSGabor Juhos struct clk *clk; 191d4a67d9dSGabor Juhos 192d4a67d9dSGabor Juhos clk = clk_get(NULL, "cpu"); 193d4a67d9dSGabor Juhos if (IS_ERR(clk)) 194d4a67d9dSGabor Juhos panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); 195d4a67d9dSGabor Juhos 196d4a67d9dSGabor Juhos mips_hpt_frequency = clk_get_rate(clk) / 2; 197d4a67d9dSGabor Juhos } 198d4a67d9dSGabor Juhos 199d4a67d9dSGabor Juhos static int __init ath79_setup(void) 200d4a67d9dSGabor Juhos { 2016eae43c5SGabor Juhos ath79_gpio_init(); 202d4a67d9dSGabor Juhos ath79_register_uart(); 203858f763cSGabor Juhos ath79_register_wdt(); 2040aabf1a4SGabor Juhos 2050aabf1a4SGabor Juhos mips_machine_setup(); 2060aabf1a4SGabor Juhos 207d4a67d9dSGabor Juhos return 0; 208d4a67d9dSGabor Juhos } 209d4a67d9dSGabor Juhos 210d4a67d9dSGabor Juhos arch_initcall(ath79_setup); 2110aabf1a4SGabor Juhos 2120aabf1a4SGabor Juhos static void __init ath79_generic_init(void) 2130aabf1a4SGabor Juhos { 2140aabf1a4SGabor Juhos /* Nothing to do */ 2150aabf1a4SGabor Juhos } 2160aabf1a4SGabor Juhos 2170aabf1a4SGabor Juhos MIPS_MACHINE(ATH79_MACH_GENERIC, 2180aabf1a4SGabor Juhos "Generic", 2190aabf1a4SGabor Juhos "Generic AR71XX/AR724X/AR913X based board", 2200aabf1a4SGabor Juhos ath79_generic_init); 221