1d4a67d9dSGabor Juhos /* 2d4a67d9dSGabor Juhos * Atheros AR71XX/AR724X/AR913X common routines 3d4a67d9dSGabor Juhos * 442184768SGabor Juhos * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 542184768SGabor Juhos * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 6d4a67d9dSGabor Juhos * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 7d4a67d9dSGabor Juhos * 842184768SGabor Juhos * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 942184768SGabor Juhos * 10d4a67d9dSGabor Juhos * This program is free software; you can redistribute it and/or modify it 11d4a67d9dSGabor Juhos * under the terms of the GNU General Public License version 2 as published 12d4a67d9dSGabor Juhos * by the Free Software Foundation. 13d4a67d9dSGabor Juhos */ 14d4a67d9dSGabor Juhos 15d4a67d9dSGabor Juhos #include <linux/kernel.h> 16d4a67d9dSGabor Juhos #include <linux/module.h> 17d4a67d9dSGabor Juhos #include <linux/types.h> 18d4a67d9dSGabor Juhos #include <linux/spinlock.h> 19d4a67d9dSGabor Juhos 20d4a67d9dSGabor Juhos #include <asm/mach-ath79/ath79.h> 21d4a67d9dSGabor Juhos #include <asm/mach-ath79/ar71xx_regs.h> 22d4a67d9dSGabor Juhos #include "common.h" 23d4a67d9dSGabor Juhos 24d4a67d9dSGabor Juhos static DEFINE_SPINLOCK(ath79_device_reset_lock); 25d4a67d9dSGabor Juhos 26d4a67d9dSGabor Juhos u32 ath79_cpu_freq; 27d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_cpu_freq); 28d4a67d9dSGabor Juhos 29d4a67d9dSGabor Juhos u32 ath79_ahb_freq; 30d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_ahb_freq); 31d4a67d9dSGabor Juhos 32d4a67d9dSGabor Juhos u32 ath79_ddr_freq; 33d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_ddr_freq); 34d4a67d9dSGabor Juhos 35d4a67d9dSGabor Juhos enum ath79_soc_type ath79_soc; 36be5f3623SGabor Juhos unsigned int ath79_soc_rev; 37d4a67d9dSGabor Juhos 38d4a67d9dSGabor Juhos void __iomem *ath79_pll_base; 39d4a67d9dSGabor Juhos void __iomem *ath79_reset_base; 40d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_reset_base); 4124b0e3e8SAlban Bedel static void __iomem *ath79_ddr_base; 4224b0e3e8SAlban Bedel static void __iomem *ath79_ddr_wb_flush_base; 4324b0e3e8SAlban Bedel static void __iomem *ath79_ddr_pci_win_base; 4424b0e3e8SAlban Bedel 4524b0e3e8SAlban Bedel void ath79_ddr_ctrl_init(void) 4624b0e3e8SAlban Bedel { 4724b0e3e8SAlban Bedel ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, 4824b0e3e8SAlban Bedel AR71XX_DDR_CTRL_SIZE); 496241bf6aSFelix Fietkau if (soc_is_ar913x() || soc_is_ar724x() || soc_is_ar933x()) { 5024b0e3e8SAlban Bedel ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; 5124b0e3e8SAlban Bedel ath79_ddr_pci_win_base = 0; 526241bf6aSFelix Fietkau } else { 536241bf6aSFelix Fietkau ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; 546241bf6aSFelix Fietkau ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; 5524b0e3e8SAlban Bedel } 5624b0e3e8SAlban Bedel } 5724b0e3e8SAlban Bedel EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); 58d4a67d9dSGabor Juhos 59d4a67d9dSGabor Juhos void ath79_ddr_wb_flush(u32 reg) 60d4a67d9dSGabor Juhos { 6124b0e3e8SAlban Bedel void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg; 62d4a67d9dSGabor Juhos 63d4a67d9dSGabor Juhos /* Flush the DDR write buffer. */ 64d4a67d9dSGabor Juhos __raw_writel(0x1, flush_reg); 65d4a67d9dSGabor Juhos while (__raw_readl(flush_reg) & 0x1) 66d4a67d9dSGabor Juhos ; 67d4a67d9dSGabor Juhos 68d4a67d9dSGabor Juhos /* It must be run twice. */ 69d4a67d9dSGabor Juhos __raw_writel(0x1, flush_reg); 70d4a67d9dSGabor Juhos while (__raw_readl(flush_reg) & 0x1) 71d4a67d9dSGabor Juhos ; 72d4a67d9dSGabor Juhos } 73d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush); 74d4a67d9dSGabor Juhos 7524b0e3e8SAlban Bedel void ath79_ddr_set_pci_windows(void) 7624b0e3e8SAlban Bedel { 7724b0e3e8SAlban Bedel BUG_ON(!ath79_ddr_pci_win_base); 7824b0e3e8SAlban Bedel 79*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0x0); 80*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 0x4); 81*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 0x8); 82*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 0xc); 83*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 0x10); 84*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 0x14); 85*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 0x18); 86*9184dc8fSFelix Fietkau __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 0x1c); 8724b0e3e8SAlban Bedel } 8824b0e3e8SAlban Bedel EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); 8924b0e3e8SAlban Bedel 90d4a67d9dSGabor Juhos void ath79_device_reset_set(u32 mask) 91d4a67d9dSGabor Juhos { 92d4a67d9dSGabor Juhos unsigned long flags; 93d4a67d9dSGabor Juhos u32 reg; 94d4a67d9dSGabor Juhos u32 t; 95d4a67d9dSGabor Juhos 96d4a67d9dSGabor Juhos if (soc_is_ar71xx()) 97d4a67d9dSGabor Juhos reg = AR71XX_RESET_REG_RESET_MODULE; 98d4a67d9dSGabor Juhos else if (soc_is_ar724x()) 99d4a67d9dSGabor Juhos reg = AR724X_RESET_REG_RESET_MODULE; 100d4a67d9dSGabor Juhos else if (soc_is_ar913x()) 101d4a67d9dSGabor Juhos reg = AR913X_RESET_REG_RESET_MODULE; 1027ee15d8aSGabor Juhos else if (soc_is_ar933x()) 1037ee15d8aSGabor Juhos reg = AR933X_RESET_REG_RESET_MODULE; 10442184768SGabor Juhos else if (soc_is_ar934x()) 10542184768SGabor Juhos reg = AR934X_RESET_REG_RESET_MODULE; 1067d4c2af9SGabor Juhos else if (soc_is_qca955x()) 1077d4c2af9SGabor Juhos reg = QCA955X_RESET_REG_RESET_MODULE; 108d4a67d9dSGabor Juhos else 109d4a67d9dSGabor Juhos BUG(); 110d4a67d9dSGabor Juhos 111d4a67d9dSGabor Juhos spin_lock_irqsave(&ath79_device_reset_lock, flags); 112d4a67d9dSGabor Juhos t = ath79_reset_rr(reg); 113d4a67d9dSGabor Juhos ath79_reset_wr(reg, t | mask); 114d4a67d9dSGabor Juhos spin_unlock_irqrestore(&ath79_device_reset_lock, flags); 115d4a67d9dSGabor Juhos } 116d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_device_reset_set); 117d4a67d9dSGabor Juhos 118d4a67d9dSGabor Juhos void ath79_device_reset_clear(u32 mask) 119d4a67d9dSGabor Juhos { 120d4a67d9dSGabor Juhos unsigned long flags; 121d4a67d9dSGabor Juhos u32 reg; 122d4a67d9dSGabor Juhos u32 t; 123d4a67d9dSGabor Juhos 124d4a67d9dSGabor Juhos if (soc_is_ar71xx()) 125d4a67d9dSGabor Juhos reg = AR71XX_RESET_REG_RESET_MODULE; 126d4a67d9dSGabor Juhos else if (soc_is_ar724x()) 127d4a67d9dSGabor Juhos reg = AR724X_RESET_REG_RESET_MODULE; 128d4a67d9dSGabor Juhos else if (soc_is_ar913x()) 129d4a67d9dSGabor Juhos reg = AR913X_RESET_REG_RESET_MODULE; 1307ee15d8aSGabor Juhos else if (soc_is_ar933x()) 1317ee15d8aSGabor Juhos reg = AR933X_RESET_REG_RESET_MODULE; 13242184768SGabor Juhos else if (soc_is_ar934x()) 13342184768SGabor Juhos reg = AR934X_RESET_REG_RESET_MODULE; 1347d4c2af9SGabor Juhos else if (soc_is_qca955x()) 1357d4c2af9SGabor Juhos reg = QCA955X_RESET_REG_RESET_MODULE; 136d4a67d9dSGabor Juhos else 137d4a67d9dSGabor Juhos BUG(); 138d4a67d9dSGabor Juhos 139d4a67d9dSGabor Juhos spin_lock_irqsave(&ath79_device_reset_lock, flags); 140d4a67d9dSGabor Juhos t = ath79_reset_rr(reg); 141d4a67d9dSGabor Juhos ath79_reset_wr(reg, t & ~mask); 142d4a67d9dSGabor Juhos spin_unlock_irqrestore(&ath79_device_reset_lock, flags); 143d4a67d9dSGabor Juhos } 144d4a67d9dSGabor Juhos EXPORT_SYMBOL_GPL(ath79_device_reset_clear); 145