0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/module.h>
0008 #include <linux/io.h>
0009 #include <linux/delay.h>
0010 #include <linux/atomic.h>
0011 #include "cns3xxx.h"
0012 #include "pm.h"
0013 #include "core.h"
0014
0015 void cns3xxx_pwr_clk_en(unsigned int block)
0016 {
0017 u32 reg = __raw_readl(PM_CLK_GATE_REG);
0018
0019 reg |= (block & PM_CLK_GATE_REG_MASK);
0020 __raw_writel(reg, PM_CLK_GATE_REG);
0021 }
0022 EXPORT_SYMBOL(cns3xxx_pwr_clk_en);
0023
0024 void cns3xxx_pwr_clk_dis(unsigned int block)
0025 {
0026 u32 reg = __raw_readl(PM_CLK_GATE_REG);
0027
0028 reg &= ~(block & PM_CLK_GATE_REG_MASK);
0029 __raw_writel(reg, PM_CLK_GATE_REG);
0030 }
0031 EXPORT_SYMBOL(cns3xxx_pwr_clk_dis);
0032
0033 void cns3xxx_pwr_power_up(unsigned int block)
0034 {
0035 u32 reg = __raw_readl(PM_PLL_HM_PD_CTRL_REG);
0036
0037 reg &= ~(block & CNS3XXX_PWR_PLL_ALL);
0038 __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
0039
0040
0041 udelay(300);
0042 };
0043 EXPORT_SYMBOL(cns3xxx_pwr_power_up);
0044
0045 void cns3xxx_pwr_power_down(unsigned int block)
0046 {
0047 u32 reg = __raw_readl(PM_PLL_HM_PD_CTRL_REG);
0048
0049
0050 reg |= (block & CNS3XXX_PWR_PLL_ALL);
0051 __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
0052 };
0053 EXPORT_SYMBOL(cns3xxx_pwr_power_down);
0054
0055 static void cns3xxx_pwr_soft_rst_force(unsigned int block)
0056 {
0057 u32 reg = __raw_readl(PM_SOFT_RST_REG);
0058
0059
0060
0061
0062
0063 if (block & 0x30000001) {
0064 reg &= ~(block & PM_SOFT_RST_REG_MASK);
0065 } else {
0066 reg &= ~(block & PM_SOFT_RST_REG_MASK);
0067 __raw_writel(reg, PM_SOFT_RST_REG);
0068 reg |= (block & PM_SOFT_RST_REG_MASK);
0069 }
0070
0071 __raw_writel(reg, PM_SOFT_RST_REG);
0072 }
0073
0074 void cns3xxx_pwr_soft_rst(unsigned int block)
0075 {
0076 static unsigned int soft_reset;
0077
0078 if (soft_reset & block) {
0079
0080 return;
0081 } else {
0082 soft_reset |= block;
0083 }
0084 cns3xxx_pwr_soft_rst_force(block);
0085 }
0086 EXPORT_SYMBOL(cns3xxx_pwr_soft_rst);
0087
0088 void cns3xxx_restart(enum reboot_mode mode, const char *cmd)
0089 {
0090
0091
0092
0093
0094 cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(GLOBAL));
0095 }
0096
0097
0098
0099
0100
0101
0102
0103 int cns3xxx_cpu_clock(void)
0104 {
0105 u32 reg = __raw_readl(PM_CLK_CTRL_REG);
0106 int cpu;
0107 int cpu_sel;
0108 int div_sel;
0109
0110 cpu_sel = (reg >> PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL) & 0xf;
0111 div_sel = (reg >> PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV) & 0x3;
0112
0113 cpu = (300 + ((cpu_sel / 3) * 100) + ((cpu_sel % 3) * 33)) >> div_sel;
0114
0115 return cpu;
0116 }
0117 EXPORT_SYMBOL(cns3xxx_cpu_clock);
0118
0119 atomic_t usb_pwr_ref = ATOMIC_INIT(0);
0120 EXPORT_SYMBOL(usb_pwr_ref);