Merge branch 'develop-3.0-rk2928' of ssh://10.10.10.29/rk/kernel into develop-3.0-rk2928

This commit is contained in:
zsq
2012-08-16 14:43:23 +08:00
10 changed files with 679 additions and 55 deletions

View File

@@ -203,6 +203,7 @@ static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width)
#ifdef CONFIG_WIFI_CONTROL_FUNC
#define RK30SDK_WIFI_GPIO_POWER_N RK2928_PIN0_PD6
#define RK29SDK_WIFI_GPIO_RESET_N RK2928_PIN3_PC2
#define PREALLOC_WLAN_SEC_NUM 4
#define PREALLOC_WLAN_BUF_NUM 160
@@ -309,12 +310,12 @@ static int __init rk29sdk_wifi_bt_gpio_control_init(void)
return -1;
}
/*if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) {
if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) {
pr_info("%s: request wifi reset gpio failed\n", __func__);
gpio_free(RK30SDK_WIFI_GPIO_POWER_N);
return -1;
}
/*
if (gpio_request(RK29SDK_BT_GPIO_RESET_N, "bt reset")) {
pr_info("%s: request bt reset gpio failed\n", __func__);
gpio_free(RK29SDK_WIFI_GPIO_RESET_N);
@@ -322,7 +323,7 @@ static int __init rk29sdk_wifi_bt_gpio_control_init(void)
}*/
gpio_direction_output(RK30SDK_WIFI_GPIO_POWER_N, GPIO_LOW);
//gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
//gpio_direction_output(RK29SDK_BT_GPIO_RESET_N, GPIO_LOW);
#if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
@@ -351,12 +352,12 @@ static int rk29sdk_wifi_power(int on)
pr_info("%s: %d\n", __func__, on);
if (on){
gpio_set_value(RK30SDK_WIFI_GPIO_POWER_N, GPIO_HIGH);
mdelay(50);
#if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13
#endif
//gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH);
gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH);
mdelay(100);
pr_info("wifi turn on power\n");
}else{
@@ -373,7 +374,7 @@ static int rk29sdk_wifi_power(int on)
// {
// pr_info("wifi shouldn't shut off power, bt is using it!\n");
// }
//gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
}
@@ -385,8 +386,8 @@ static int rk29sdk_wifi_reset_state;
static int rk29sdk_wifi_reset(int on)
{
pr_info("%s: %d\n", __func__, on);
//gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, on);
//mdelay(100);
gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, on);
mdelay(100);
rk29sdk_wifi_reset_state = on;
return 0;
}

View File

@@ -237,6 +237,10 @@ int tps65910_post_init(struct tps65910 *tps65910)
struct regulator *dcdc;
struct regulator *ldo;
printk("%s,line=%d\n", __func__,__LINE__);
#ifdef CONFIG_RK30_PWM_REGULATOR
platform_device_register(&pwm_regulator_device[0]);
#endif
dcdc = regulator_get(NULL, "vio"); //vcc_io
regulator_set_voltage(dcdc, 3300000, 3300000);
@@ -315,15 +319,6 @@ int tps65910_post_init(struct tps65910 *tps65910)
regulator_put(ldo);
udelay(100);
#ifdef CONFIG_RK30_PWM_REGULATOR
dcdc = regulator_get(NULL, "vdd_core"); // vdd_log
regulator_set_voltage(dcdc, 1100000, 1100000);
regulator_enable(dcdc);
printk("%s set vdd_core=%dmV end\n", __func__, regulator_get_voltage(dcdc));
regulator_put(dcdc);
udelay(100);
#endif
printk("%s,line=%d END\n", __func__,__LINE__);
return 0;

View File

@@ -379,6 +379,59 @@ static struct platform_device device_ion = {
};
#endif
#if CONFIG_RK30_PWM_REGULATOR
const static int pwm_voltage_map[] = {
1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000
};
static struct regulator_consumer_supply pwm_dcdc1_consumers[] = {
{
.supply = "vdd_core",
}
};
struct regulator_init_data pwm_regulator_init_dcdc[1] =
{
{
.constraints = {
.name = "PWM_DCDC1",
.min_uV = 600000,
.max_uV = 1800000, //0.6-1.8V
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
},
.num_consumer_supplies = ARRAY_SIZE(pwm_dcdc1_consumers),
.consumer_supplies = pwm_dcdc1_consumers,
},
};
static struct pwm_platform_data pwm_regulator_info[1] = {
{
.pwm_id = 2,
.pwm_gpio = RK2928_PIN0_PD4,
.pwm_iomux_name = GPIO0D4_PWM_2_NAME,
.pwm_iomux_pwm = GPIO0D_PWM_2,
.pwm_iomux_gpio = GPIO0D_GPIO0D4,
.pwm_voltage = 1200000,
.suspend_voltage = 1050000,
.min_uV = 1000000,
.max_uV = 1400000,
.coefficient = 455, //45.5%
.pwm_voltage_map = pwm_voltage_map,
.init_data = &pwm_regulator_init_dcdc[0],
},
};
struct platform_device pwm_regulator_device[1] = {
{
.name = "pwm-voltage-regulator",
.id = 0,
.dev = {
.platform_data = &pwm_regulator_info[0],
}
},
};
#endif
/**************************************************************************************************
* SDMMC devices, include the module of SD,MMC,and sdio.noted by xbw at 2012-03-05
**************************************************************************************************/
@@ -717,10 +770,15 @@ static void __init rk30_i2c_register_board_info(void)
//end of i2c
#define POWER_ON_PIN RK2928_PIN3_PC5 //power_hold
static void rk30_pm_power_off(void)
static void rk2928_pm_power_off(void)
{
printk(KERN_ERR "rk30_pm_power_off start...\n");
printk(KERN_ERR "rk2928_pm_power_off start...\n");
#if defined(CONFIG_MFD_TPS65910)
tps65910_device_shutdown();//tps65910 shutdown
#endif
gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
};
static void __init rk2928_board_init(void)
@@ -729,7 +787,7 @@ static void __init rk2928_board_init(void)
gpio_direction_output(POWER_ON_PIN, GPIO_HIGH);
gpio_free(POWER_ON_PIN);
pm_power_off = rk30_pm_power_off;
pm_power_off = rk2928_pm_power_off;
rk30_i2c_register_board_info();
spi_register_board_info(board_spi_devices, ARRAY_SIZE(board_spi_devices));

View File

@@ -62,6 +62,7 @@ struct pll_clk_set {
#define CLKDATA_LOG(fmt, args...) do {} while(0)
#endif
#define CLKDATA_ERR(fmt, args...) printk(KERN_ERR "CLKDATA_ERR:\t"fmt, ##args)
#define CLKDATA_WARNNING(fmt, args...) printk("CLKDATA_WANNING:\t"fmt, ##args)
#define cru_readl(offset) readl_relaxed(RK2928_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel_relaxed(v, RK2928_CRU_BASE + offset); dsb(); } while (0)
@@ -330,6 +331,12 @@ static int clksel_set_rate_freediv(struct clk *clk, unsigned long rate)
CLKDATA_DBG("clksel_set_rate_freediv for clock %s to rate %ld (div %d)\n", clk->name, rate, div + 1);
return 0;
}
if (div == clk->div_max - 1) {
CLKDATA_WARNNING("%s clk=%s, div=%u, rate=%lu, new_rate=%u\n",
__func__, clk->name, div, rate, new_rate);
set_cru_bits_w_msk(div,clk->div_mask,clk->div_shift,clk->clksel_con);
return 0;
}
}
return -ENOENT;
}

View File

@@ -4,7 +4,7 @@
#include <plat/sram.h>
#define SRAM_LOOPS_PER_USEC 24
#define SRAM_LOOP(loops) do { unsigned int i = (loops); if (i < 7) i = 7; barrier(); while (--i) barrier(); } while (0)
#define SRAM_LOOP(loops) do { unsigned int i = (loops); if (i < 7) i = 7; barrier(); asm volatile(".align 4; 1: subs %0, %0, #1; bne 1b;" : "+r" (i)); } while (0)
/* delay on slow mode */
#define sram_udelay(usecs) SRAM_LOOP((usecs)*SRAM_LOOPS_PER_USEC)
/* delay on deep slow mode */

View File

@@ -14,13 +14,47 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <mach/pmu.h>
#include <mach/board.h>
#include <mach/system.h>
#include <mach/sram.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/cru.h>
#define cru_readl(offset) readl_relaxed(RK2928_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel_relaxed(v, RK2928_CRU_BASE + offset); dsb(); } while (0)
#define grf_readl(offset) readl_relaxed(RK2928_GRF_BASE + offset)
#define grf_writel(v, offset) do { writel_relaxed(v, RK2928_GRF_BASE + offset); dsb(); } while (0)
#define gate_save_soc_clk(val, _save, cons, w_msk) \
do { \
(_save) = cru_readl(cons); \
cru_writel(((~(val) | (_save)) & (w_msk)) | ((w_msk) << 16), cons); \
} while (0)
void __sramfunc sram_printch(char byte)
{
#ifdef DEBUG_UART_BASE
u32 clk_gate2, clk_gate4, clk_gate8;
gate_save_soc_clk(0
| (1 << CLK_GATE_ACLK_PERIPH % 16)
| (1 << CLK_GATE_HCLK_PERIPH % 16)
| (1 << CLK_GATE_PCLK_PERIPH % 16)
, clk_gate2, CRU_CLKGATES_CON(2), 0
| (1 << ((CLK_GATE_ACLK_PERIPH % 16) + 16))
| (1 << ((CLK_GATE_HCLK_PERIPH % 16) + 16))
| (1 << ((CLK_GATE_PCLK_PERIPH % 16) + 16)));
gate_save_soc_clk((1 << CLK_GATE_ACLK_CPU_PERI % 16)
, clk_gate4, CRU_CLKGATES_CON(4),
(1 << ((CLK_GATE_ACLK_CPU_PERI % 16) + 16)));
gate_save_soc_clk((1 << ((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16)),
clk_gate8, CRU_CLKGATES_CON(8),
(1 << (((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16) + 16)));
sram_udelay(1);
writel_relaxed(byte, DEBUG_UART_BASE);
dsb();
@@ -28,8 +62,427 @@ void __sramfunc sram_printch(char byte)
while (!(readl_relaxed(DEBUG_UART_BASE + 0x14) & 0x40))
barrier();
cru_writel(0xffff0000 | clk_gate2, CRU_CLKGATES_CON(2));
cru_writel(0xffff0000 | clk_gate4, CRU_CLKGATES_CON(4));
cru_writel(0xffff0000 | clk_gate8, CRU_CLKGATES_CON(8));
if (byte == '\n')
sram_printch('\r');
#endif
}
__weak void __sramfunc ddr_suspend(void) {}
__weak void __sramfunc ddr_resume(void) {}
__weak uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) { return nMHz; }
#ifdef CONFIG_DDR_TEST
static int ddr_debug=0;
module_param(ddr_debug, int, 0644);
static int inline calc_crc32(u32 addr, size_t len)
{
return crc32_le(~0, (const unsigned char *)addr, len);
}
static void ddr_testmode(void)
{
int32_t g_crc1, g_crc2;
uint32_t nMHz;
uint32_t n = 0;
uint32_t min,max;
extern char _stext[], _etext[];
if (ddr_debug == 1) {
max=500;
min=100;
for (;;) {
sram_printascii("\n change freq:");
g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
do
{
nMHz = min + random32();
nMHz %= max;
}while(nMHz < min);
sram_printhex(nMHz);
sram_printch(' ');
nMHz = ddr_change_freq(nMHz);
sram_printhex(n++);
sram_printch(' ');
g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
if (g_crc1!=g_crc2) {
sram_printascii("fail\n");
}
//ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
// sram_printascii("change freq success\n");
}
} else if(ddr_debug == 2) {
for (;;) {
sram_printch(' ');
sram_printch('9');
sram_printch('9');
sram_printch('9');
sram_printch(' ');
g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
nMHz = (random32()>>13);// 16.7s max
ddr_suspend();
sram_udelay(nMHz);
ddr_resume();
sram_printhex(nMHz);
sram_printch(' ');
sram_printhex(n++);
g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
if (g_crc1 != g_crc2) {
sram_printch(' ');
sram_printch('f');
sram_printch('a');
sram_printch('i');
sram_printch('l');
}
// ddr_print("check image crc32 fail!, count:%d\n", n++);
// sram_printascii("self refresh fail\n");
//else
//ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
// sram_printascii("self refresh success\n");
}
} else if (ddr_debug == 3) {
extern int memtester(void);
memtester();
}
else
{
ddr_change_freq(ddr_debug);
ddr_debug=0;
}
}
#else
static void ddr_testmode(void) {}
#endif
static noinline void rk2928_pm_dump_irq(void)
{
u32 irq_gpio = (readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + (IRQ_GPIO0 / 32) * 4) >> (IRQ_GPIO0 % 32)) & 0xF;
printk("wakeup irq: %08x %08x %08x\n",
readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 4),
readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 8),
readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 12));
if (irq_gpio & 1)
printk("wakeup gpio0: %08x\n", readl_relaxed(RK2928_GPIO0_BASE + GPIO_INT_STATUS));
if (irq_gpio & 2)
printk("wakeup gpio1: %08x\n", readl_relaxed(RK2928_GPIO1_BASE + GPIO_INT_STATUS));
if (irq_gpio & 4)
printk("wakeup gpio2: %08x\n", readl_relaxed(RK2928_GPIO2_BASE + GPIO_INT_STATUS));
if (irq_gpio & 8)
printk("wakeup gpio3: %08x\n", readl_relaxed(RK2928_GPIO3_BASE + GPIO_INT_STATUS));
}
#define DUMP_GPIO_INTEN(ID) \
do { \
u32 en = readl_relaxed(RK2928_GPIO##ID##_BASE + GPIO_INTEN); \
if (en) { \
sram_printascii("GPIO" #ID "_INTEN: "); \
sram_printhex(en); \
sram_printch('\n'); \
} \
} while (0)
static noinline void rk2928_pm_dump_inten(void)
{
DUMP_GPIO_INTEN(0);
DUMP_GPIO_INTEN(1);
DUMP_GPIO_INTEN(2);
DUMP_GPIO_INTEN(3);
}
static void pm_pll_wait_lock(int pll_idx)
{
u32 pll_state[4] = { 1, 0, 2, 3 };
u32 bit = 0x10u << pll_state[pll_idx];
u32 delay = pll_idx == APLL_ID ? 24000000U : 2400000000U;
while (delay > 0) {
if (grf_readl(GRF_SOC_STATUS0) & bit)
break;
delay--;
}
if (delay == 0) {
//CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit);
sram_printch('p');
sram_printch('l');
sram_printch('l');
sram_printhex(pll_idx);
sram_printch('\n');
}
}
#define power_on_pll(id) \
cru_writel(PLL_PWR_DN_W_MSK|PLL_PWR_ON,PLL_CONS((id),3));\
pm_pll_wait_lock((id))
#define DDR_SAVE_SP(save_sp) do { save_sp = ddr_save_sp(((unsigned long)SRAM_DATA_END & (~7))); } while (0)
#define DDR_RESTORE_SP(save_sp) do { ddr_save_sp(save_sp); } while (0)
static unsigned long save_sp;
static noinline void interface_ctr_reg_pread(void)
{
u32 addr;
flush_cache_all();
outer_flush_all();
local_flush_tlb_all();
for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)SRAM_DATA_END; addr += PAGE_SIZE)
readl_relaxed(addr);
readl_relaxed(RK2928_GRF_BASE);
readl_relaxed(RK2928_DDR_PCTL_BASE);
readl_relaxed(RK2928_DDR_PHY_BASE);
// readl_relaxed(RK2928_I2C1_BASE);
}
__weak void board_gpio_suspend(void) {}
__weak void board_gpio_resume(void) {}
__weak void __sramfunc board_pmu_suspend(void) {}
__weak void __sramfunc board_pmu_resume(void) {}
__weak void __sramfunc rk30_suspend_voltage_set(unsigned int vol) {}
__weak void __sramfunc rk30_suspend_voltage_resume(unsigned int vol) {}
__weak void rk30_pwm_suspend_voltage_set(void) {}
__weak void rk30_pwm_resume_voltage_set(void) {}
__weak void __sramfunc rk30_pwm_logic_suspend_voltage(void) {}
__weak void __sramfunc rk30_pwm_logic_resume_voltage(void) {}
static void __sramfunc rk2928_sram_suspend(void)
{
u32 cru_clksel0_con;
u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
int i;
sram_printch('5');
ddr_suspend();
sram_printch('6');
rk30_suspend_voltage_set(1000000);
rk30_pwm_logic_suspend_voltage();
sram_printch('7');
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
}
gate_save_soc_clk(0
| (1 << CLK_GATE_CORE_PERIPH)
| (1 << CLK_GATE_DDRPHY_SRC)
| (1 << CLK_GATE_ACLK_CPU)
| (1 << CLK_GATE_HCLK_CPU)
| (1 << CLK_GATE_PCLK_CPU)
| (1 << CLK_GATE_ACLK_CORE)
, clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff);
if (!(clkgt_regs[8] & (0xf << (CLK_GATE_PCLK_GPIO0 % 16)))) {
gate_save_soc_clk(0
| (1 << CLK_GATE_PERIPH_SRC % 16)
| (1 << CLK_GATE_PCLK_PERIPH % 16)
, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
} else {
gate_save_soc_clk(0, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
}
gate_save_soc_clk(0
| (1 << CLK_GATE_ACLK_STRC_SYS % 16)
| (1 << CLK_GATE_ACLK_INTMEM % 16)
, clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_PCLK_GRF % 16)
| (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
, clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff);
gate_save_soc_clk(0, clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_CLK_L2C % 16)
, clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff);
board_pmu_suspend();
cru_clksel0_con = cru_readl(CRU_CLKSELS_CON(0));
cru_writel((0x1f << 16) | 0x1f, CRU_CLKSELS_CON(0));
dsb();
wfi();
cru_writel((0x1f << 16) | cru_clksel0_con, CRU_CLKSELS_CON(0));
board_pmu_resume();
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
}
sram_printch('7');
rk30_pwm_logic_resume_voltage();
rk30_suspend_voltage_resume(1100000);
sram_printch('6');
ddr_resume();
sram_printch('5');
}
static void noinline rk2928_suspend(void)
{
DDR_SAVE_SP(save_sp);
rk2928_sram_suspend();
DDR_RESTORE_SP(save_sp);
}
static int rk2928_pm_enter(suspend_state_t state)
{
u32 i;
u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
u32 clk_sel0, clk_sel1, clk_sel10;
u32 cru_mode_con;
// dump GPIO INTEN for debug
rk2928_pm_dump_inten();
sram_printch('0');
#ifdef CONFIG_DDR_TEST
// memory tester
if (ddr_debug != 0)
ddr_testmode();
#endif
sram_printch('1');
local_fiq_disable();
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
}
gate_save_soc_clk(0
| (1 << CLK_GATE_CORE_PERIPH)
| (1 << CLK_GATE_DDRPHY_SRC)
| (1 << CLK_GATE_ACLK_CPU)
| (1 << CLK_GATE_HCLK_CPU)
| (1 << CLK_GATE_PCLK_CPU)
| (1 << CLK_GATE_ACLK_CORE)
, clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff);
gate_save_soc_clk(0, clkgt_regs[1], CRU_CLKGATES_CON(1), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_PERIPH_SRC % 16)
| (1 << CLK_GATE_PCLK_PERIPH % 16)
| (1 << CLK_GATE_ACLK_PERIPH % 16)
, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
gate_save_soc_clk(0, clkgt_regs[3], CRU_CLKGATES_CON(3), 0xff9f);
gate_save_soc_clk(0
| (1 << CLK_GATE_HCLK_PERI_AXI_MATRIX % 16)
| (1 << CLK_GATE_PCLK_PERI_AXI_MATRIX % 16)
| (1 << CLK_GATE_ACLK_CPU_PERI % 16)
| (1 << CLK_GATE_ACLK_PERI_AXI_MATRIX % 16)
| (1 << CLK_GATE_ACLK_STRC_SYS % 16)
| (1 << CLK_GATE_ACLK_INTMEM % 16)
, clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff);
gate_save_soc_clk(0
| (1 << CLK_GATE_PCLK_GRF % 16)
| (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
, clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff);
gate_save_soc_clk(0, clkgt_regs[6], CRU_CLKGATES_CON(6), 0xffff);
gate_save_soc_clk(0
|(1 << CLK_GATE_PCLK_PWM01%16)
, clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff);
gate_save_soc_clk(0, clkgt_regs[8], CRU_CLKGATES_CON(8), 0x01ff);
gate_save_soc_clk(0
| (1 << CLK_GATE_CLK_L2C % 16)
| (1 << CLK_GATE_HCLK_PERI_ARBI % 16)
| (1 << CLK_GATE_ACLK_PERI_NIU % 16)
, clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff);
sram_printch('2');
cru_mode_con = cru_readl(CRU_MODE_CON);
//cpll
cru_writel(PLL_MODE_SLOW(CPLL_ID), CRU_MODE_CON);
//gpll
clk_sel10 = cru_readl(CRU_CLKSELS_CON(10));
cru_writel(PLL_MODE_SLOW(GPLL_ID), CRU_MODE_CON);
cru_writel(PERI_SET_ACLK_DIV(1)
| PERI_SET_A2H_RATIO(RATIO_11)
| PERI_SET_A2P_RATIO(RATIO_11)
, CRU_CLKSELS_CON(10));
//apll
clk_sel0 = cru_readl(CRU_CLKSELS_CON(0));
clk_sel1 = cru_readl(CRU_CLKSELS_CON(1));
cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
cru_writel(CLK_CORE_DIV(1) | ACLK_CPU_DIV(1), CRU_CLKSELS_CON(0));
cru_writel(CLK_CORE_PERI_DIV(1) | ACLK_CORE_DIV(1) | HCLK_CPU_DIV(1) | PCLK_CPU_DIV(1), CRU_CLKSELS_CON(1));
sram_printch('3');
rk30_pwm_suspend_voltage_set();
board_gpio_suspend();
interface_ctr_reg_pread();
sram_printch('4');
rk2928_suspend();
sram_printch('4');
board_gpio_resume();
rk30_pwm_resume_voltage_set();
sram_printch('3');
//apll
cru_writel(0xffff0000 | clk_sel1, CRU_CLKSELS_CON(1));
cru_writel(0xffff0000 | clk_sel0, CRU_CLKSELS_CON(0));
cru_writel((PLL_MODE_MSK(APLL_ID) << 16) | (PLL_MODE_MSK(APLL_ID) & cru_mode_con), CRU_MODE_CON);
//gpll
cru_writel(0xffff0000 | clk_sel10, CRU_CLKSELS_CON(10));
cru_writel(clk_sel10, CRU_CLKSELS_CON(10));
cru_writel((PLL_MODE_MSK(GPLL_ID) << 16) | (PLL_MODE_MSK(GPLL_ID) & cru_mode_con), CRU_MODE_CON);
//cpll
cru_writel((PLL_MODE_MSK(CPLL_ID) << 16) | (PLL_MODE_MSK(CPLL_ID) & cru_mode_con), CRU_MODE_CON);
sram_printch('2');
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
}
local_fiq_enable();
sram_printch('1');
sram_printascii("0\n");
rk2928_pm_dump_irq();
return 0;
}
static int rk2928_pm_prepare(void)
{
/* disable entering idle by disable_hlt() */
disable_hlt();
return 0;
}
static void rk2928_pm_finish(void)
{
enable_hlt();
}
static struct platform_suspend_ops rk2928_pm_ops = {
.enter = rk2928_pm_enter,
.valid = suspend_valid_only_mem,
.prepare = rk2928_pm_prepare,
.finish = rk2928_pm_finish,
};
static int __init rk2928_pm_init(void)
{
suspend_set_ops(&rk2928_pm_ops);
#ifdef CONFIG_EARLYSUSPEND
pm_set_vt_switch(0); /* disable vt switch while suspend */
#endif
return 0;
}
__initcall(rk2928_pm_init);

View File

@@ -318,10 +318,9 @@ static void rk30_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
spin_unlock_irqrestore(&bank->lock, flags);
}
static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned enable)
{
#if defined(CONFIG_ARCH_RK30)
#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)
struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip);
unsigned long flags;
@@ -335,7 +334,6 @@ static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, uns
return 0;
}
static int rk30_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset)
{
return chip->base + offset;

View File

@@ -111,7 +111,9 @@ struct rk29_i2c_data {
#endif
};
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
static struct wake_lock idlelock; /* only for i2c0 */
#endif
static void rk29_set_ack(struct rk29_i2c_data *i2c)
{
@@ -558,8 +560,10 @@ static int rk29_i2c_xfer(struct i2c_adapter *adap,
i2c->udelay_time = RK29_UDELAY_TIME(i2c->scl_rate);
i2c->ack_timeout = RK29_I2C_ACK_TIMEOUT_COUNT * i2c->udelay_time;
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
if (adap->nr == 0)
wake_lock(&idlelock);
#endif
for (i = 0; i < num; i++)
{
@@ -572,8 +576,10 @@ static int rk29_i2c_xfer(struct i2c_adapter *adap,
}
}
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
if (adap->nr == 0)
wake_unlock(&idlelock);
#endif
/*
if( --retry && num < 0)
@@ -887,7 +893,9 @@ static struct platform_driver rk29_i2c_driver = {
static int __init rk29_i2c_adap_init(void)
{
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30)
wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "i2c0");
#endif
return platform_driver_register(&rk29_i2c_driver);
}

View File

@@ -66,34 +66,37 @@ struct rk_pwm_dcdc {
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK30_PWM01_BASE+(id>>1)*0x20000+id*0x10))
#elif defined(CONFIG_ARCH_RK29)
#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10))
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10))
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10))
#elif defined(CONFIG_ARCH_RK2928)
#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK2928_PWM_BASE+id*0x10))
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK2928_PWM_BASE+id*0x10))
#endif
const static int pwm_voltage_map[] = {
850000,875000,900000,925000,950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000
1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000
};
static struct clk *pwm_clk[2];
static struct rk_pwm_dcdc *g_dcdc;
static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
{
u32 divh,divTotal;
int id = pdata->pwm_id;
unsigned long clkrate;
if ( id >3 || id <0 )
/*
if ( id >2 || id <0 )
{
printk("%s:pwm id error,id=%d\n",__func__,id);
return -1;
}
if((id==0) || (id == 1))
*/
clkrate = clk_get_rate(pwm_clk[0]);
else
clkrate = clk_get_rate(pwm_clk[1]);
DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate);
DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate);
if(rate == 0)
{
// iomux pwm to gpio
@@ -101,9 +104,9 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
//disable pull up or down
gpio_pull_updown(pdata->pwm_gpio,PullDisable);
// set gpio to low level
gpio_set_value(pdata->pwm_gpio,GPIO_LOW);
gpio_direction_output(pdata->pwm_gpio,GPIO_LOW);
}
else if (rate <= 100)
else if (rate < 100)
{
// iomux pwm
rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm);
@@ -119,6 +122,16 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
pwm_write_reg(id,PWM_REG_CNTR,0);
pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|PWM_DIV|PWM_ENABLE|PWM_TimeEN);
}
else if (rate == 100)
{
// iomux pwm to gpio
rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_gpio);
//disable pull up or down
gpio_pull_updown(pdata->pwm_gpio,PullDisable);
// set gpio to low level
gpio_direction_output(pdata->pwm_gpio,GPIO_HIGH);
}
else
{
printk("%s:rate error\n",__func__);
@@ -132,8 +145,9 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
static int pwm_regulator_list_voltage(struct regulator_dev *dev,unsigned int index)
{
if (index < sizeof(pwm_voltage_map)/sizeof(int))
return pwm_voltage_map[index];
struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);
if (index < dcdc->desc.n_voltages)
return dcdc->pdata->pwm_voltage_map[index];
else
return -1;
}
@@ -176,15 +190,14 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
#endif
{
struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);
const int *voltage_map = pwm_voltage_map;
int min_mV = min_uV, max_mA = max_uV;
u32 size = sizeof(pwm_voltage_map)/sizeof(int), i, vol,pwm_value;
const int *voltage_map = dcdc->pdata->pwm_voltage_map;
int max = dcdc->pdata->max_uV;
int coefficient = dcdc->pdata->coefficient;
u32 size = dcdc->desc.n_voltages, i, vol,pwm_value;
DBG("%s: min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV);
if (min_mV < voltage_map[0] ||max_mA > voltage_map[size-1])
if (min_uV < voltage_map[0] ||max_uV > voltage_map[size-1])
{
printk("%s:voltage is out of table\n",__func__);
return -EINVAL;
@@ -192,7 +205,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
for (i = 0; i < size; i++)
{
if (voltage_map[i] >= min_mV)
if (voltage_map[i] >= min_uV)
break;
}
@@ -201,9 +214,8 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
dcdc->pdata->pwm_voltage = vol;
// VDD12 = 1.42 - 0.56*D , <20><><EFBFBD><EFBFBD>DΪPWMռ<4D>ձ<EFBFBD>,
pwm_value = (1325000-vol)/5800; // pwm_value %
// VDD12 = 1.40 - 0.455*D , <20><><EFBFBD><EFBFBD>DΪPWMռ<4D>ձ<EFBFBD>,
pwm_value = (max-vol)/coefficient/10; // pwm_value %, coefficient *1000
if (pwm_set_rate(dcdc->pdata,1000*1000,pwm_value)!=0)
{
@@ -242,7 +254,6 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
struct pwm_platform_data *pdata = pdev->dev.platform_data;
struct rk_pwm_dcdc *dcdc;
int pwm_id = pdata->pwm_id;
struct regulator_dev *rdev;
int id = pdev->id;
int ret ;
char gpio_name[20];
@@ -251,8 +262,23 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
return -ENODEV;
if (!pdata->pwm_voltage)
pdata->pwm_voltage = 1200000; // default 1.2v
pdata->pwm_voltage = 1100000; // default 1.1v
if(!pdata->pwm_voltage_map)
pdata->pwm_voltage_map = pwm_voltage_map;
if(!pdata->max_uV)
pdata->max_uV = 1400000;
if(!pdata->min_uV)
pdata->min_uV = 1000000;
if(pdata->suspend_voltage < pdata->min_uV)
pdata->suspend_voltage = pdata->min_uV;
if(pdata->suspend_voltage > pdata->max_uV)
pdata->suspend_voltage = pdata->max_uV;
dcdc = kzalloc(sizeof(struct rk_pwm_dcdc), GFP_KERNEL);
if (dcdc == NULL) {
dev_err(&pdev->dev, "Unable to allocate private data\n");
@@ -263,11 +289,11 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
dcdc->desc.name = dcdc->name;
dcdc->desc.id = id;
dcdc->desc.type = REGULATOR_VOLTAGE;
dcdc->desc.n_voltages = 50;
dcdc->desc.n_voltages = ARRAY_SIZE(pwm_voltage_map);
dcdc->desc.ops = &pwm_voltage_ops;
dcdc->desc.owner = THIS_MODULE;
dcdc->pdata = pdata;
printk("%s:n_voltages=%d\n",__func__,dcdc->desc.n_voltages);
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
pdata->init_data, dcdc);
if (IS_ERR(dcdc->regulator)) {
@@ -297,10 +323,17 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
pwm_clk[1] = clk_get(NULL, "pwm23");
clk_enable(pwm_clk[1]);
}
#elif defined(CONFIG_ARCH_RK2928)
pwm_clk[0] = clk_get(NULL, "pwm01");
if (IS_ERR(pwm_clk[0])) {
printk("pwm_clk get error %p\n", pwm_clk[0]);
return -EINVAL;
}
clk_enable(pwm_clk[0]);
#endif
platform_set_drvdata(pdev, dcdc);
g_dcdc = dcdc;
platform_set_drvdata(pdev, dcdc);
printk(KERN_INFO "pwm_regulator.%d: driver initialized\n",id);
return 0;
@@ -314,10 +347,73 @@ err:
}
static int __sramdata g_PWM_REG_LRC = 0;
static int __sramdata g_PWM_REG_HRC = 0;
void pwm_suspend_voltage(void)
{
struct rk_pwm_dcdc *dcdc = g_dcdc;
int suspend_voltage = 0;
int pwm_id = 0;
if(!dcdc)
return;
pwm_id = dcdc->pdata->pwm_id;
suspend_voltage = dcdc->pdata->suspend_voltage;
g_PWM_REG_LRC = pwm_read_reg(pwm_id, PWM_REG_LRC);
g_PWM_REG_HRC = pwm_read_reg(pwm_id,PWM_REG_HRC);
switch(suspend_voltage)
{
case 1000000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00
break;
case 1050000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x1c); // 1 .05
break;
case 1100000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x18); // 1 .1
break;
case 1150000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x13); // 1 .15
break;
default:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00
break;
}
}
void pwm_resume_voltage(void)
{
struct rk_pwm_dcdc *dcdc = g_dcdc;
int pwm_id = 0;
if(!dcdc)
return;
pwm_id = dcdc->pdata->pwm_id;
pwm_write_reg(pwm_id, PWM_REG_LRC, g_PWM_REG_LRC);
pwm_write_reg(pwm_id,PWM_REG_HRC, g_PWM_REG_HRC);
}
static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t state)
{
struct pwm_platform_data *pdata = pdev->dev.platform_data;
pwm_set_rate(pdata,1000*1000,0);//pwm clk will change to 24M after suspend
//struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev);
//unsigned selector = 0;
//pwm_regulator_set_voltage(dcdc->regulator, 1100000, 1100000, &selector);
DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id);
return 0;
}
@@ -325,6 +421,9 @@ static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t stat
static int pwm_regulator_resume(struct platform_device *pdev)
{
struct pwm_platform_data *pdata = pdev->dev.platform_data;
//struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev);
//unsigned selector = 0;
//pwm_regulator_set_voltage(dcdc->regulator, 1150000, 1150000, &selector);
DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id);
return 0;
}
@@ -361,7 +460,7 @@ static void __exit pwm_regulator_module_exit(void)
}
subsys_initcall(pwm_regulator_module_init);
fs_initcall(pwm_regulator_module_init);
module_exit(pwm_regulator_module_exit);

5
include/linux/regulator/rk29-pwm-regulator.h Normal file → Executable file
View File

@@ -57,6 +57,11 @@ struct pwm_platform_data {
unsigned int pwm_iomux_pwm;
int pwm_iomux_gpio;
int pwm_voltage;
int suspend_voltage;
int coefficient;
int min_uV;
int max_uV;
int *pwm_voltage_map;
struct regulator_init_data *init_data;
};