linux/arch/mips/ath79/setup.c
<<
>>
Prefs
   1/*
   2 *  Atheros AR71XX/AR724X/AR913X specific setup
   3 *
   4 *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
   5 *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
   6 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
   7 *
   8 *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
   9 *
  10 *  This program is free software; you can redistribute it and/or modify it
  11 *  under the terms of the GNU General Public License version 2 as published
  12 *  by the Free Software Foundation.
  13 */
  14
  15#include <linux/kernel.h>
  16#include <linux/init.h>
  17#include <linux/bootmem.h>
  18#include <linux/err.h>
  19#include <linux/clk.h>
  20#include <linux/clk-provider.h>
  21#include <linux/of_fdt.h>
  22
  23#include <asm/bootinfo.h>
  24#include <asm/idle.h>
  25#include <asm/time.h>           /* for mips_hpt_frequency */
  26#include <asm/reboot.h>         /* for _machine_{restart,halt} */
  27#include <asm/mips_machine.h>
  28#include <asm/prom.h>
  29#include <asm/fw/fw.h>
  30
  31#include <asm/mach-ath79/ath79.h>
  32#include <asm/mach-ath79/ar71xx_regs.h>
  33#include "common.h"
  34#include "dev-common.h"
  35#include "machtypes.h"
  36
  37#define ATH79_SYS_TYPE_LEN      64
  38
  39static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
  40
  41static void ath79_restart(char *command)
  42{
  43        ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
  44        for (;;)
  45                if (cpu_wait)
  46                        cpu_wait();
  47}
  48
  49static void ath79_halt(void)
  50{
  51        while (1)
  52                cpu_wait();
  53}
  54
  55static void __init ath79_detect_sys_type(void)
  56{
  57        char *chip = "????";
  58        u32 id;
  59        u32 major;
  60        u32 minor;
  61        u32 rev = 0;
  62
  63        id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
  64        major = id & REV_ID_MAJOR_MASK;
  65
  66        switch (major) {
  67        case REV_ID_MAJOR_AR71XX:
  68                minor = id & AR71XX_REV_ID_MINOR_MASK;
  69                rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
  70                rev &= AR71XX_REV_ID_REVISION_MASK;
  71                switch (minor) {
  72                case AR71XX_REV_ID_MINOR_AR7130:
  73                        ath79_soc = ATH79_SOC_AR7130;
  74                        chip = "7130";
  75                        break;
  76
  77                case AR71XX_REV_ID_MINOR_AR7141:
  78                        ath79_soc = ATH79_SOC_AR7141;
  79                        chip = "7141";
  80                        break;
  81
  82                case AR71XX_REV_ID_MINOR_AR7161:
  83                        ath79_soc = ATH79_SOC_AR7161;
  84                        chip = "7161";
  85                        break;
  86                }
  87                break;
  88
  89        case REV_ID_MAJOR_AR7240:
  90                ath79_soc = ATH79_SOC_AR7240;
  91                chip = "7240";
  92                rev = id & AR724X_REV_ID_REVISION_MASK;
  93                break;
  94
  95        case REV_ID_MAJOR_AR7241:
  96                ath79_soc = ATH79_SOC_AR7241;
  97                chip = "7241";
  98                rev = id & AR724X_REV_ID_REVISION_MASK;
  99                break;
 100
 101        case REV_ID_MAJOR_AR7242:
 102                ath79_soc = ATH79_SOC_AR7242;
 103                chip = "7242";
 104                rev = id & AR724X_REV_ID_REVISION_MASK;
 105                break;
 106
 107        case REV_ID_MAJOR_AR913X:
 108                minor = id & AR913X_REV_ID_MINOR_MASK;
 109                rev = id >> AR913X_REV_ID_REVISION_SHIFT;
 110                rev &= AR913X_REV_ID_REVISION_MASK;
 111                switch (minor) {
 112                case AR913X_REV_ID_MINOR_AR9130:
 113                        ath79_soc = ATH79_SOC_AR9130;
 114                        chip = "9130";
 115                        break;
 116
 117                case AR913X_REV_ID_MINOR_AR9132:
 118                        ath79_soc = ATH79_SOC_AR9132;
 119                        chip = "9132";
 120                        break;
 121                }
 122                break;
 123
 124        case REV_ID_MAJOR_AR9330:
 125                ath79_soc = ATH79_SOC_AR9330;
 126                chip = "9330";
 127                rev = id & AR933X_REV_ID_REVISION_MASK;
 128                break;
 129
 130        case REV_ID_MAJOR_AR9331:
 131                ath79_soc = ATH79_SOC_AR9331;
 132                chip = "9331";
 133                rev = id & AR933X_REV_ID_REVISION_MASK;
 134                break;
 135
 136        case REV_ID_MAJOR_AR9341:
 137                ath79_soc = ATH79_SOC_AR9341;
 138                chip = "9341";
 139                rev = id & AR934X_REV_ID_REVISION_MASK;
 140                break;
 141
 142        case REV_ID_MAJOR_AR9342:
 143                ath79_soc = ATH79_SOC_AR9342;
 144                chip = "9342";
 145                rev = id & AR934X_REV_ID_REVISION_MASK;
 146                break;
 147
 148        case REV_ID_MAJOR_AR9344:
 149                ath79_soc = ATH79_SOC_AR9344;
 150                chip = "9344";
 151                rev = id & AR934X_REV_ID_REVISION_MASK;
 152                break;
 153
 154        case REV_ID_MAJOR_QCA9556:
 155                ath79_soc = ATH79_SOC_QCA9556;
 156                chip = "9556";
 157                rev = id & QCA955X_REV_ID_REVISION_MASK;
 158                break;
 159
 160        case REV_ID_MAJOR_QCA9558:
 161                ath79_soc = ATH79_SOC_QCA9558;
 162                chip = "9558";
 163                rev = id & QCA955X_REV_ID_REVISION_MASK;
 164                break;
 165
 166        default:
 167                panic("ath79: unknown SoC, id:0x%08x", id);
 168        }
 169
 170        ath79_soc_rev = rev;
 171
 172        if (soc_is_qca955x())
 173                sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u",
 174                        chip, rev);
 175        else
 176                sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
 177        pr_info("SoC: %s\n", ath79_sys_type);
 178}
 179
 180const char *get_system_type(void)
 181{
 182        return ath79_sys_type;
 183}
 184
 185int get_c0_perfcount_int(void)
 186{
 187        return ATH79_MISC_IRQ(5);
 188}
 189EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
 190
 191unsigned int get_c0_compare_int(void)
 192{
 193        return CP0_LEGACY_COMPARE_IRQ;
 194}
 195
 196void __init plat_mem_setup(void)
 197{
 198        unsigned long fdt_start;
 199
 200        set_io_port_base(KSEG1);
 201
 202        /* Get the position of the FDT passed by the bootloader */
 203        fdt_start = fw_getenvl("fdt_start");
 204        if (fdt_start)
 205                __dt_setup_arch((void *)KSEG0ADDR(fdt_start));
 206        else if (fw_passed_dtb)
 207                __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb));
 208
 209        if (mips_machtype != ATH79_MACH_GENERIC_OF) {
 210                ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
 211                                                   AR71XX_RESET_SIZE);
 212                ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
 213                                                 AR71XX_PLL_SIZE);
 214                ath79_detect_sys_type();
 215                ath79_ddr_ctrl_init();
 216
 217                detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
 218
 219                /* OF machines should use the reset driver */
 220                _machine_restart = ath79_restart;
 221        }
 222
 223        _machine_halt = ath79_halt;
 224        pm_power_off = ath79_halt;
 225}
 226
 227static void __init ath79_of_plat_time_init(void)
 228{
 229        struct device_node *np;
 230        struct clk *clk;
 231        unsigned long cpu_clk_rate;
 232
 233        of_clk_init(NULL);
 234
 235        np = of_get_cpu_node(0, NULL);
 236        if (!np) {
 237                pr_err("Failed to get CPU node\n");
 238                return;
 239        }
 240
 241        clk = of_clk_get(np, 0);
 242        if (IS_ERR(clk)) {
 243                pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
 244                return;
 245        }
 246
 247        cpu_clk_rate = clk_get_rate(clk);
 248
 249        pr_info("CPU clock: %lu.%03lu MHz\n",
 250                cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000);
 251
 252        mips_hpt_frequency = cpu_clk_rate / 2;
 253
 254        clk_put(clk);
 255}
 256
 257void __init plat_time_init(void)
 258{
 259        unsigned long cpu_clk_rate;
 260        unsigned long ahb_clk_rate;
 261        unsigned long ddr_clk_rate;
 262        unsigned long ref_clk_rate;
 263
 264        if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) {
 265                ath79_of_plat_time_init();
 266                return;
 267        }
 268
 269        ath79_clocks_init();
 270
 271        cpu_clk_rate = ath79_get_sys_clk_rate("cpu");
 272        ahb_clk_rate = ath79_get_sys_clk_rate("ahb");
 273        ddr_clk_rate = ath79_get_sys_clk_rate("ddr");
 274        ref_clk_rate = ath79_get_sys_clk_rate("ref");
 275
 276        pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n",
 277                cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000,
 278                ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000,
 279                ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000,
 280                ref_clk_rate / 1000000, (ref_clk_rate / 1000) % 1000);
 281
 282        mips_hpt_frequency = cpu_clk_rate / 2;
 283}
 284
 285static int __init ath79_setup(void)
 286{
 287        if  (mips_machtype == ATH79_MACH_GENERIC_OF)
 288                return 0;
 289
 290        ath79_gpio_init();
 291        ath79_register_uart();
 292        ath79_register_wdt();
 293
 294        mips_machine_setup();
 295
 296        return 0;
 297}
 298
 299arch_initcall(ath79_setup);
 300
 301void __init device_tree_init(void)
 302{
 303        unflatten_and_copy_device_tree();
 304}
 305
 306MIPS_MACHINE(ATH79_MACH_GENERIC,
 307             "Generic",
 308             "Generic AR71XX/AR724X/AR913X based board",
 309             NULL);
 310
 311MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
 312             "DTB",
 313             "Generic AR71XX/AR724X/AR913X based board (DT)",
 314             NULL);
 315