0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/export.h>
0011 #include <linux/spinlock.h>
0012 #include <asm/mach-au1x00/au1000.h>
0013
0014 #define VSS_GATE 0x00
0015 #define VSS_CLKRST 0x04
0016 #define VSS_FTR 0x08
0017
0018 #define VSS_ADDR(blk) (KSEG1ADDR(AU1300_VSS_PHYS_ADDR) + (blk * 0x0c))
0019
0020 static DEFINE_SPINLOCK(au1300_vss_lock);
0021
0022
0023 static inline void __enable_block(int block)
0024 {
0025 void __iomem *base = (void __iomem *)VSS_ADDR(block);
0026
0027 __raw_writel(3, base + VSS_CLKRST);
0028 wmb();
0029
0030 __raw_writel(0x01fffffe, base + VSS_GATE);
0031 wmb();
0032
0033
0034 __raw_writel(0x01, base + VSS_FTR);
0035 wmb();
0036 __raw_writel(0x03, base + VSS_FTR);
0037 wmb();
0038 __raw_writel(0x07, base + VSS_FTR);
0039 wmb();
0040 __raw_writel(0x0f, base + VSS_FTR);
0041 wmb();
0042
0043 __raw_writel(0x01ffffff, base + VSS_GATE);
0044 wmb();
0045
0046 __raw_writel(2, base + VSS_CLKRST);
0047 wmb();
0048
0049 __raw_writel(0x1f, base + VSS_FTR);
0050 wmb();
0051 }
0052
0053
0054 static inline void __disable_block(int block)
0055 {
0056 void __iomem *base = (void __iomem *)VSS_ADDR(block);
0057
0058 __raw_writel(0x0f, base + VSS_FTR);
0059 wmb();
0060 __raw_writel(0, base + VSS_GATE);
0061 wmb();
0062 __raw_writel(3, base + VSS_CLKRST);
0063 wmb();
0064 __raw_writel(1, base + VSS_CLKRST);
0065 wmb();
0066 __raw_writel(0, base + VSS_FTR);
0067 wmb();
0068 }
0069
0070 void au1300_vss_block_control(int block, int enable)
0071 {
0072 unsigned long flags;
0073
0074 if (alchemy_get_cputype() != ALCHEMY_CPU_AU1300)
0075 return;
0076
0077
0078 spin_lock_irqsave(&au1300_vss_lock, flags);
0079 if (enable)
0080 __enable_block(block);
0081 else
0082 __disable_block(block);
0083 spin_unlock_irqrestore(&au1300_vss_lock, flags);
0084 }
0085 EXPORT_SYMBOL_GPL(au1300_vss_block_control);