1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d4a67d9dSGabor Juhos /*
3d4a67d9dSGabor Juhos * Atheros AR71XX/AR724X/AR913X specific setup
4d4a67d9dSGabor Juhos *
5d8411466SGabor Juhos * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
6d4a67d9dSGabor Juhos * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
7d4a67d9dSGabor Juhos * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
8d4a67d9dSGabor Juhos *
9d8411466SGabor Juhos * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
10d4a67d9dSGabor Juhos */
11d4a67d9dSGabor Juhos
12d4a67d9dSGabor Juhos #include <linux/kernel.h>
13d4a67d9dSGabor Juhos #include <linux/init.h>
1462e59c4eSStephen Boyd #include <linux/io.h>
1557c8a661SMike Rapoport #include <linux/memblock.h>
16d4a67d9dSGabor Juhos #include <linux/err.h>
17d4a67d9dSGabor Juhos #include <linux/clk.h>
18d2936bd0SGeert Uytterhoeven #include <linux/of_clk.h>
1903c8c407SAlban Bedel #include <linux/of_fdt.h>
2051fa4f89SJohn Crispin #include <linux/irqchip.h>
21d4a67d9dSGabor Juhos
22d4a67d9dSGabor Juhos #include <asm/bootinfo.h>
23bdc92d74SRalf Baechle #include <asm/idle.h>
24d4a67d9dSGabor Juhos #include <asm/time.h> /* for mips_hpt_frequency */
25d4a67d9dSGabor Juhos #include <asm/reboot.h> /* for _machine_{restart,halt} */
2603c8c407SAlban Bedel #include <asm/prom.h>
2703c8c407SAlban Bedel #include <asm/fw/fw.h>
28d4a67d9dSGabor Juhos
29d4a67d9dSGabor Juhos #include <asm/mach-ath79/ath79.h>
30d4a67d9dSGabor Juhos #include <asm/mach-ath79/ar71xx_regs.h>
31d4a67d9dSGabor Juhos #include "common.h"
32d4a67d9dSGabor Juhos
33d4a67d9dSGabor Juhos #define ATH79_SYS_TYPE_LEN 64
34d4a67d9dSGabor Juhos
35d4a67d9dSGabor Juhos static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
36d4a67d9dSGabor Juhos
ath79_halt(void)37d4a67d9dSGabor Juhos static void ath79_halt(void)
38d4a67d9dSGabor Juhos {
39d4a67d9dSGabor Juhos while (1)
40d4a67d9dSGabor Juhos cpu_wait();
41d4a67d9dSGabor Juhos }
42d4a67d9dSGabor Juhos
ath79_detect_sys_type(void)43d4a67d9dSGabor Juhos static void __init ath79_detect_sys_type(void)
44d4a67d9dSGabor Juhos {
45d4a67d9dSGabor Juhos char *chip = "????";
46d4a67d9dSGabor Juhos u32 id;
47d4a67d9dSGabor Juhos u32 major;
48d4a67d9dSGabor Juhos u32 minor;
49d4a67d9dSGabor Juhos u32 rev = 0;
50af2d1b52SMatthias Schiffer u32 ver = 1;
51d4a67d9dSGabor Juhos
52d4a67d9dSGabor Juhos id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
53d4a67d9dSGabor Juhos major = id & REV_ID_MAJOR_MASK;
54d4a67d9dSGabor Juhos
55d4a67d9dSGabor Juhos switch (major) {
56d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR71XX:
57d4a67d9dSGabor Juhos minor = id & AR71XX_REV_ID_MINOR_MASK;
58d4a67d9dSGabor Juhos rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
59d4a67d9dSGabor Juhos rev &= AR71XX_REV_ID_REVISION_MASK;
60d4a67d9dSGabor Juhos switch (minor) {
61d4a67d9dSGabor Juhos case AR71XX_REV_ID_MINOR_AR7130:
62d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7130;
63d4a67d9dSGabor Juhos chip = "7130";
64d4a67d9dSGabor Juhos break;
65d4a67d9dSGabor Juhos
66d4a67d9dSGabor Juhos case AR71XX_REV_ID_MINOR_AR7141:
67d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7141;
68d4a67d9dSGabor Juhos chip = "7141";
69d4a67d9dSGabor Juhos break;
70d4a67d9dSGabor Juhos
71d4a67d9dSGabor Juhos case AR71XX_REV_ID_MINOR_AR7161:
72d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7161;
73d4a67d9dSGabor Juhos chip = "7161";
74d4a67d9dSGabor Juhos break;
75d4a67d9dSGabor Juhos }
76d4a67d9dSGabor Juhos break;
77d4a67d9dSGabor Juhos
78d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR7240:
79d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7240;
80d4a67d9dSGabor Juhos chip = "7240";
818bed1288SGabor Juhos rev = id & AR724X_REV_ID_REVISION_MASK;
82d4a67d9dSGabor Juhos break;
83d4a67d9dSGabor Juhos
84d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR7241:
85d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7241;
86d4a67d9dSGabor Juhos chip = "7241";
878bed1288SGabor Juhos rev = id & AR724X_REV_ID_REVISION_MASK;
88d4a67d9dSGabor Juhos break;
89d4a67d9dSGabor Juhos
90d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR7242:
91d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR7242;
92d4a67d9dSGabor Juhos chip = "7242";
938bed1288SGabor Juhos rev = id & AR724X_REV_ID_REVISION_MASK;
94d4a67d9dSGabor Juhos break;
95d4a67d9dSGabor Juhos
96d4a67d9dSGabor Juhos case REV_ID_MAJOR_AR913X:
97d4a67d9dSGabor Juhos minor = id & AR913X_REV_ID_MINOR_MASK;
98d4a67d9dSGabor Juhos rev = id >> AR913X_REV_ID_REVISION_SHIFT;
99d4a67d9dSGabor Juhos rev &= AR913X_REV_ID_REVISION_MASK;
100d4a67d9dSGabor Juhos switch (minor) {
101d4a67d9dSGabor Juhos case AR913X_REV_ID_MINOR_AR9130:
102d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR9130;
103d4a67d9dSGabor Juhos chip = "9130";
104d4a67d9dSGabor Juhos break;
105d4a67d9dSGabor Juhos
106d4a67d9dSGabor Juhos case AR913X_REV_ID_MINOR_AR9132:
107d4a67d9dSGabor Juhos ath79_soc = ATH79_SOC_AR9132;
108d4a67d9dSGabor Juhos chip = "9132";
109d4a67d9dSGabor Juhos break;
110d4a67d9dSGabor Juhos }
111d4a67d9dSGabor Juhos break;
112d4a67d9dSGabor Juhos
11380a7ed81SGabor Juhos case REV_ID_MAJOR_AR9330:
11480a7ed81SGabor Juhos ath79_soc = ATH79_SOC_AR9330;
11580a7ed81SGabor Juhos chip = "9330";
11680a7ed81SGabor Juhos rev = id & AR933X_REV_ID_REVISION_MASK;
11780a7ed81SGabor Juhos break;
11880a7ed81SGabor Juhos
11980a7ed81SGabor Juhos case REV_ID_MAJOR_AR9331:
12080a7ed81SGabor Juhos ath79_soc = ATH79_SOC_AR9331;
12180a7ed81SGabor Juhos chip = "9331";
12280a7ed81SGabor Juhos rev = id & AR933X_REV_ID_REVISION_MASK;
12380a7ed81SGabor Juhos break;
12480a7ed81SGabor Juhos
125d8411466SGabor Juhos case REV_ID_MAJOR_AR9341:
126d8411466SGabor Juhos ath79_soc = ATH79_SOC_AR9341;
127d8411466SGabor Juhos chip = "9341";
128d8411466SGabor Juhos rev = id & AR934X_REV_ID_REVISION_MASK;
129d8411466SGabor Juhos break;
130d8411466SGabor Juhos
131d8411466SGabor Juhos case REV_ID_MAJOR_AR9342:
132d8411466SGabor Juhos ath79_soc = ATH79_SOC_AR9342;
133d8411466SGabor Juhos chip = "9342";
134d8411466SGabor Juhos rev = id & AR934X_REV_ID_REVISION_MASK;
135d8411466SGabor Juhos break;
136d8411466SGabor Juhos
137d8411466SGabor Juhos case REV_ID_MAJOR_AR9344:
138d8411466SGabor Juhos ath79_soc = ATH79_SOC_AR9344;
139d8411466SGabor Juhos chip = "9344";
140d8411466SGabor Juhos rev = id & AR934X_REV_ID_REVISION_MASK;
141d8411466SGabor Juhos break;
142d8411466SGabor Juhos
143af2d1b52SMatthias Schiffer case REV_ID_MAJOR_QCA9533_V2:
144af2d1b52SMatthias Schiffer ver = 2;
145af2d1b52SMatthias Schiffer ath79_soc_rev = 2;
146c9b02990SLiangliang Huang fallthrough;
147af2d1b52SMatthias Schiffer case REV_ID_MAJOR_QCA9533:
148af2d1b52SMatthias Schiffer ath79_soc = ATH79_SOC_QCA9533;
149af2d1b52SMatthias Schiffer chip = "9533";
150af2d1b52SMatthias Schiffer rev = id & QCA953X_REV_ID_REVISION_MASK;
151af2d1b52SMatthias Schiffer break;
152af2d1b52SMatthias Schiffer
1532e6c91e3SGabor Juhos case REV_ID_MAJOR_QCA9556:
1542e6c91e3SGabor Juhos ath79_soc = ATH79_SOC_QCA9556;
1552e6c91e3SGabor Juhos chip = "9556";
1562e6c91e3SGabor Juhos rev = id & QCA955X_REV_ID_REVISION_MASK;
1572e6c91e3SGabor Juhos break;
1582e6c91e3SGabor Juhos
1592e6c91e3SGabor Juhos case REV_ID_MAJOR_QCA9558:
1602e6c91e3SGabor Juhos ath79_soc = ATH79_SOC_QCA9558;
1612e6c91e3SGabor Juhos chip = "9558";
1622e6c91e3SGabor Juhos rev = id & QCA955X_REV_ID_REVISION_MASK;
1632e6c91e3SGabor Juhos break;
1642e6c91e3SGabor Juhos
165af2d1b52SMatthias Schiffer case REV_ID_MAJOR_QCA956X:
166af2d1b52SMatthias Schiffer ath79_soc = ATH79_SOC_QCA956X;
167af2d1b52SMatthias Schiffer chip = "956X";
168af2d1b52SMatthias Schiffer rev = id & QCA956X_REV_ID_REVISION_MASK;
169af2d1b52SMatthias Schiffer break;
170af2d1b52SMatthias Schiffer
171*a0b8cd5cSWenli Looi case REV_ID_MAJOR_QCN550X:
172*a0b8cd5cSWenli Looi ath79_soc = ATH79_SOC_QCA956X;
173*a0b8cd5cSWenli Looi chip = "550X";
174*a0b8cd5cSWenli Looi rev = id & QCA956X_REV_ID_REVISION_MASK;
175*a0b8cd5cSWenli Looi break;
176*a0b8cd5cSWenli Looi
177af2d1b52SMatthias Schiffer case REV_ID_MAJOR_TP9343:
178af2d1b52SMatthias Schiffer ath79_soc = ATH79_SOC_TP9343;
179af2d1b52SMatthias Schiffer chip = "9343";
180af2d1b52SMatthias Schiffer rev = id & QCA956X_REV_ID_REVISION_MASK;
181af2d1b52SMatthias Schiffer break;
182af2d1b52SMatthias Schiffer
183d4a67d9dSGabor Juhos default:
184ab75dc02SRalf Baechle panic("ath79: unknown SoC, id:0x%08x", id);
185d4a67d9dSGabor Juhos }
186d4a67d9dSGabor Juhos
187af2d1b52SMatthias Schiffer if (ver == 1)
188be5f3623SGabor Juhos ath79_soc_rev = rev;
189be5f3623SGabor Juhos
190af2d1b52SMatthias Schiffer if (soc_is_qca953x() || soc_is_qca955x() || soc_is_qca956x())
191af2d1b52SMatthias Schiffer sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u",
192af2d1b52SMatthias Schiffer chip, ver, rev);
193af2d1b52SMatthias Schiffer else if (soc_is_tp9343())
194af2d1b52SMatthias Schiffer sprintf(ath79_sys_type, "Qualcomm Atheros TP%s rev %u",
1952e6c91e3SGabor Juhos chip, rev);
1962e6c91e3SGabor Juhos else
197d4a67d9dSGabor Juhos sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
198d4a67d9dSGabor Juhos pr_info("SoC: %s\n", ath79_sys_type);
199d4a67d9dSGabor Juhos }
200d4a67d9dSGabor Juhos
get_system_type(void)201d4a67d9dSGabor Juhos const char *get_system_type(void)
202d4a67d9dSGabor Juhos {
203d4a67d9dSGabor Juhos return ath79_sys_type;
204d4a67d9dSGabor Juhos }
205d4a67d9dSGabor Juhos
get_c0_compare_int(void)206078a55fcSPaul Gortmaker unsigned int get_c0_compare_int(void)
207d4a67d9dSGabor Juhos {
208d4a67d9dSGabor Juhos return CP0_LEGACY_COMPARE_IRQ;
209d4a67d9dSGabor Juhos }
210d4a67d9dSGabor Juhos
plat_mem_setup(void)211d4a67d9dSGabor Juhos void __init plat_mem_setup(void)
212d4a67d9dSGabor Juhos {
213b83ba0b9SThomas Bogendoerfer void *dtb;
21403c8c407SAlban Bedel
215d4a67d9dSGabor Juhos set_io_port_base(KSEG1);
216d4a67d9dSGabor Juhos
21703c8c407SAlban Bedel /* Get the position of the FDT passed by the bootloader */
218b83ba0b9SThomas Bogendoerfer dtb = (void *)fw_getenvl("fdt_start");
219b83ba0b9SThomas Bogendoerfer if (dtb == NULL)
220b83ba0b9SThomas Bogendoerfer dtb = get_fdt();
221b83ba0b9SThomas Bogendoerfer
222b83ba0b9SThomas Bogendoerfer if (dtb)
223b83ba0b9SThomas Bogendoerfer __dt_setup_arch((void *)KSEG0ADDR(dtb));
22403c8c407SAlban Bedel
2254bdc0d67SChristoph Hellwig ath79_reset_base = ioremap(AR71XX_RESET_BASE,
226d4a67d9dSGabor Juhos AR71XX_RESET_SIZE);
2274bdc0d67SChristoph Hellwig ath79_pll_base = ioremap(AR71XX_PLL_BASE,
228d4a67d9dSGabor Juhos AR71XX_PLL_SIZE);
2295011a7e8SAlban Bedel ath79_detect_sys_type();
23024b0e3e8SAlban Bedel ath79_ddr_ctrl_init();
231d4a67d9dSGabor Juhos
2329b75733bSJohn Crispin detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
233f4fe969dSAntony Pavlov
234d4a67d9dSGabor Juhos _machine_halt = ath79_halt;
235d4a67d9dSGabor Juhos pm_power_off = ath79_halt;
236d4a67d9dSGabor Juhos }
237d4a67d9dSGabor Juhos
plat_time_init(void)2383a77e0d7SJohn Crispin void __init plat_time_init(void)
2393bdf1071SAntony Pavlov {
2403bdf1071SAntony Pavlov struct device_node *np;
2413bdf1071SAntony Pavlov struct clk *clk;
2423bdf1071SAntony Pavlov unsigned long cpu_clk_rate;
2433bdf1071SAntony Pavlov
2443bdf1071SAntony Pavlov of_clk_init(NULL);
2453bdf1071SAntony Pavlov
2463bdf1071SAntony Pavlov np = of_get_cpu_node(0, NULL);
2473bdf1071SAntony Pavlov if (!np) {
2483bdf1071SAntony Pavlov pr_err("Failed to get CPU node\n");
2493bdf1071SAntony Pavlov return;
2503bdf1071SAntony Pavlov }
2513bdf1071SAntony Pavlov
2523bdf1071SAntony Pavlov clk = of_clk_get(np, 0);
2533bdf1071SAntony Pavlov if (IS_ERR(clk)) {
2543bdf1071SAntony Pavlov pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
2553bdf1071SAntony Pavlov return;
2563bdf1071SAntony Pavlov }
2573bdf1071SAntony Pavlov
2583bdf1071SAntony Pavlov cpu_clk_rate = clk_get_rate(clk);
2593bdf1071SAntony Pavlov
2603bdf1071SAntony Pavlov pr_info("CPU clock: %lu.%03lu MHz\n",
2613bdf1071SAntony Pavlov cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000);
2623bdf1071SAntony Pavlov
2633bdf1071SAntony Pavlov mips_hpt_frequency = cpu_clk_rate / 2;
2643bdf1071SAntony Pavlov
2653bdf1071SAntony Pavlov clk_put(clk);
2663bdf1071SAntony Pavlov }
2673bdf1071SAntony Pavlov
arch_init_irq(void)26851fa4f89SJohn Crispin void __init arch_init_irq(void)
26951fa4f89SJohn Crispin {
27051fa4f89SJohn Crispin irqchip_init();
27151fa4f89SJohn Crispin }
272