1 /*
2  *  Atheros AR71XX/AR724X/AR913X common routines
3  *
4  *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6  *
7  *  This program is free software; you can redistribute it and/or modify it
8  *  under the terms of the GNU General Public License version 2 as published
9  *  by the Free Software Foundation.
10  */
11 
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/spinlock.h>
16 
17 #include <asm/mach-ath79/ath79.h>
18 #include <asm/mach-ath79/ar71xx_regs.h>
19 #include "common.h"
20 
21 static DEFINE_SPINLOCK(ath79_device_reset_lock);
22 
23 u32 ath79_cpu_freq;
24 EXPORT_SYMBOL_GPL(ath79_cpu_freq);
25 
26 u32 ath79_ahb_freq;
27 EXPORT_SYMBOL_GPL(ath79_ahb_freq);
28 
29 u32 ath79_ddr_freq;
30 EXPORT_SYMBOL_GPL(ath79_ddr_freq);
31 
32 enum ath79_soc_type ath79_soc;
33 
34 void __iomem *ath79_pll_base;
35 void __iomem *ath79_reset_base;
36 EXPORT_SYMBOL_GPL(ath79_reset_base);
37 void __iomem *ath79_ddr_base;
38 
ath79_ddr_wb_flush(u32 reg)39 void ath79_ddr_wb_flush(u32 reg)
40 {
41 	void __iomem *flush_reg = ath79_ddr_base + reg;
42 
43 	/* Flush the DDR write buffer. */
44 	__raw_writel(0x1, flush_reg);
45 	while (__raw_readl(flush_reg) & 0x1)
46 		;
47 
48 	/* It must be run twice. */
49 	__raw_writel(0x1, flush_reg);
50 	while (__raw_readl(flush_reg) & 0x1)
51 		;
52 }
53 EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
54 
ath79_device_reset_set(u32 mask)55 void ath79_device_reset_set(u32 mask)
56 {
57 	unsigned long flags;
58 	u32 reg;
59 	u32 t;
60 
61 	if (soc_is_ar71xx())
62 		reg = AR71XX_RESET_REG_RESET_MODULE;
63 	else if (soc_is_ar724x())
64 		reg = AR724X_RESET_REG_RESET_MODULE;
65 	else if (soc_is_ar913x())
66 		reg = AR913X_RESET_REG_RESET_MODULE;
67 	else
68 		BUG();
69 
70 	spin_lock_irqsave(&ath79_device_reset_lock, flags);
71 	t = ath79_reset_rr(reg);
72 	ath79_reset_wr(reg, t | mask);
73 	spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
74 }
75 EXPORT_SYMBOL_GPL(ath79_device_reset_set);
76 
ath79_device_reset_clear(u32 mask)77 void ath79_device_reset_clear(u32 mask)
78 {
79 	unsigned long flags;
80 	u32 reg;
81 	u32 t;
82 
83 	if (soc_is_ar71xx())
84 		reg = AR71XX_RESET_REG_RESET_MODULE;
85 	else if (soc_is_ar724x())
86 		reg = AR724X_RESET_REG_RESET_MODULE;
87 	else if (soc_is_ar913x())
88 		reg = AR913X_RESET_REG_RESET_MODULE;
89 	else
90 		BUG();
91 
92 	spin_lock_irqsave(&ath79_device_reset_lock, flags);
93 	t = ath79_reset_rr(reg);
94 	ath79_reset_wr(reg, t & ~mask);
95 	spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
96 }
97 EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
98