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