static int rk3288_sys_set_power_domain(enum pmu_power_domain pd, bool on) { u32 clks_ungating[RK3288_CRU_CLKGATES_CON_CNT]; u32 clks_save[RK3288_CRU_CLKGATES_CON_CNT]; u32 i, ret; for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) { clks_save[i] = cru_readl(RK3288_CRU_CLKGATES_CON(i)); clks_ungating[i] = 0; } switch (pd) { case PD_GPU: /* gpu */ clks_ungating[5] = 1 << 7; /* aclk_gpu */ clks_ungating[18] = 1 << 0; break; case PD_VIDEO: /* aclk_vdpu_src hclk_vpu aclk_vepu_src */ clks_ungating[3] = 1 << 11 | 1 << 10 | 1 << 9; /* hclk_video aclk_video */ clks_ungating[9] = 1 << 1 | 1 << 0; break; case PD_VIO: /* aclk_lcdc0/1_src dclk_lcdc0/1_src rga_core aclk_rga_src */ /* edp_24m edp isp isp_jpeg */ clks_ungating[3] = 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 1 << 5 | 1 << 12 | 1 << 13 | 1 << 14 | 1 << 15; clks_ungating[15] = 0xffff; clks_ungating[16] = 0x0fff; break; case PD_HEVC: /* hevc_core hevc_cabac aclk_hevc */ clks_ungating[13] = 1 << 15 | 1 << 14 | 1 << 13; break; #if 0 case PD_CS: clks_ungating[12] = 1 << 11 | 1 < 10 | 1 << 9 | 1 << 8; break; #endif default: break; } for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) { if (clks_ungating[i]) cru_writel(clks_ungating[i] << 16, RK3288_CRU_CLKGATES_CON(i)); } ret = rk3288_pmu_set_power_domain(pd, on); for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) { if (clks_ungating[i]) cru_writel(clks_save[i] | 0xffff0000, RK3288_CRU_CLKGATES_CON(i)); } return ret; }
static u32 spdif_clk_enter() { u32 clk = cru_readl(CRU_CLKSEL5_CON); cru_writel(0x1ffff, CRU_CLKSEL5_CON); mdelay(1); return clk; }
static void __sramfunc rk29_pwm_set_core_voltage(unsigned int uV) { u32 gate1; gate1 = cru_readl(CRU_CLKGATE1_CON); cru_writel(gate1 & ~((1 << CLK_GATE_PCLK_PEIRPH % 32) | (1 << CLK_GATE_ACLK_PEIRPH % 32) | (1 << CLK_GATE_ACLK_CPU_PERI % 32)), CRU_CLKGATE1_CON); /* iomux pwm2 */ writel((readl(RK29_GRF_BASE + 0x58) & ~(0x3<<6)) | (0x2<<6), RK29_GRF_BASE + 0x58); if (uV) { pwm_lrc = pwm_read_reg(PWM_REG_LRC); pwm_hrc = pwm_read_reg(PWM_REG_HRC); } pwm_write_reg(PWM_REG_CTRL, PWM_DIV|PWM_RESET); if (uV == 1000000) { pwm_write_reg(PWM_REG_LRC, 12); pwm_write_reg(PWM_REG_HRC, 10); } else { pwm_write_reg(PWM_REG_LRC, pwm_lrc); pwm_write_reg(PWM_REG_HRC, pwm_hrc); } pwm_write_reg(PWM_REG_CNTR, 0); pwm_write_reg(PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TimeEN); LOOP(10 * 1000 * LOOPS_PER_USEC); /* delay 10ms */ cru_writel(gate1, CRU_CLKGATE1_CON); }
/* Waiting for pll locked by pll id */ static void rkclk_pll_wait_lock(enum rk_plls_id pll_id) { /* delay for pll lock */ while (1) { if (cru_readl(PLL_CONS(pll_id, 1)) & (0x01 << 31)) { break; } clk_loop_delayus(1); } }
static inline void timer_clk(u32 n, bool enable) { u32 gate = n ? CLK_GATE_TIMER1 : CLK_GATE_TIMER0; u32 offset = CRU_CLKGATE0_CON + (gate / 32) * 4; u32 v = cru_readl(offset); if (enable) v &= ~(1 << (gate % 32)); else v |= 1 << (gate % 32); barrier(); cru_writel(v, offset); barrier(); }
int rk3288_sys_set_power_domain(enum pmu_power_domain pd, bool on) { u32 clks_ungating[RK3288_CRU_CLKGATES_CON_CNT]; u32 clks_save[RK3288_CRU_CLKGATES_CON_CNT]; u32 i,ret; for(i=0;i<RK3288_CRU_CLKGATES_CON_CNT;i++) { clks_save[i]=cru_readl(RK3288_CRU_CLKGATES_CON(i)); clks_ungating[i]=0; } switch(pd) { case PD_GPU: clks_ungating[5]=0x1<<7; break; case PD_VIDEO: clks_ungating[3]=0x1<<11|0x1<<10|0x1<<9; break; case PD_VIO: clks_ungating[3]=0x1<<0|0x1<<2|0x1<<5|0x1<<4|0x1<<1|0x1<<3|0x1<<12|0x1<<13 |0x1<<14|0x1<<15|0x1<<12|0x1<<11; break; case PD_HEVC: clks_ungating[13]=0x1<<15|0x1<<14|0x1<<13; break; #if 0 case PD_CS: clks_ungating[12]=0x1<<11|0x1<10|0x1<<9|0x1<<8; break; #endif default: break; } for(i=0;i<RK3288_CRU_CLKGATES_CON_CNT;i++) { if(clks_ungating[i]) cru_writel(clks_ungating[i]<<16,RK3288_CRU_CLKGATES_CON(i)); } ret=rk3288_pmu_set_power_domain(pd,on); for(i=0;i<RK3288_CRU_CLKGATES_CON_CNT;i++) { if(clks_ungating[i]) cru_writel(clks_save[i]|0xffff0000,RK3288_CRU_CLKGATES_CON(i)); } return ret; }
/* Get pll rate by id */ static uint32 rkclk_pll_get_rate(enum rk_plls_id pll_id) { uint32 nr, no, nf; uint32 con; con = cru_readl(PLL_CONS(pll_id, 3)); con = (con & PLL_MODE_MSK) >> 8; if (con == 0) { /* slow mode */ return (24 * MHZ); } else if (con == 1) { /* normal mode */ con = cru_readl(PLL_CONS(pll_id, 0)); no = PLL_NO(con); nr = PLL_NR(con); con = cru_readl(PLL_CONS(pll_id, 1)); nf = PLL_NF(con); return (24 * nf / (nr * no)) * MHZ; } else { /* deep slow mode */ return 32768; } }
void __sramfunc sram_i2c_init() { unsigned int div, divl, divh; //enable cru_clkgate8 clock data[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_CLKID(8))); cru_writel(CLK_GATE_W_MSK(CLK_GATE_PCLK_I2C1)|CLK_UN_GATE(CLK_GATE_PCLK_I2C1), CLK_GATE_CLKID_CONS(CLK_GATE_PCLK_I2C1)); data[2] = readl_relaxed(RK30_GRF_BASE + GRF_GPIO_IOMUX); writel_relaxed(data[2]| I2C_GRF_GPIO_IOMUX, RK30_GRF_BASE + GRF_GPIO_IOMUX); div = 0x1e; divh = divl = 0xf; writel_relaxed(I2C_CLKDIV_VAL(divl, divh), SRAM_I2C_ADDRBASE + I2C_CLKDIV); data[3] = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CLKDIV); }
static void rk29_pm_power_off(void) { int count = 0; local_irq_disable(); local_fiq_disable(); printk(KERN_ERR "rk29_pm_power_off start...\n"); /* arm enter slow mode */ cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON); LOOP(LOOPS_PER_USEC); while (1) { /* shut down the power by GPIO. */ if (gpio_get_value(POWER_ON_PIN) == GPIO_HIGH) { printk("POWER_ON_PIN is high\n"); gpio_set_value(POWER_ON_PIN, GPIO_LOW); } LOOP(5 * LOOPS_PER_MSEC); /* only normal power off can restart system safely */ if (system_state != SYSTEM_POWER_OFF) continue; if (gpio_get_value(PLAY_ON_PIN) != GPIO_HIGH) { if (!count) printk("PLAY_ON_PIN is low\n"); if (50 == count) /* break if keep low about 250ms */ break; count++; } else { count = 0; } } printk("system reboot\n"); gpio_set_value(POWER_ON_PIN, GPIO_HIGH); system_state = SYSTEM_RESTART; arm_pm_restart(0, NULL); while (1); }
/* Set pll mode by id, normal mode or slow mode */ static void rkclk_pll_set_mode(enum rk_plls_id pll_id, int pll_mode) { uint32 con; uint32 nr, dly; con = cru_readl(PLL_CONS(pll_id, 0)); nr = PLL_NR(con); dly = (nr * 500) / 24 + 1; if (pll_mode == RKCLK_PLL_MODE_NORMAL) { cru_writel(PLL_PWR_ON | PLL_PWR_DN_W_MSK, PLL_CONS(pll_id, 3)); clk_loop_delayus(dly); rkclk_pll_wait_lock(pll_id); /* PLL enter normal-mode */ cru_writel(PLL_MODE_NORM | PLL_MODE_W_MSK, PLL_CONS(pll_id, 3)); } else { /* PLL enter slow-mode */ cru_writel(PLL_MODE_SLOW | PLL_MODE_W_MSK, PLL_CONS(pll_id, 3)); cru_writel(PLL_PWR_DN | PLL_PWR_DN_W_MSK, PLL_CONS(pll_id, 3)); } }
void __sramfunc sram_i2c_init(void) { unsigned int div, divl, divh; //enable cru_clkgate8 clock data[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_CLKID(8))); #if defined (CONFIG_MACH_RK2928_SDK) || defined( CONFIG_ARCH_RK3026_TB)||defined(CONFIG_ARCH_RK3028A_TB) cru_writel(CLK_GATE_W_MSK(CLK_GATE_PCLK_I2C1)|CLK_UN_GATE(CLK_GATE_PCLK_I2C1), CLK_GATE_CLKID_CONS(CLK_GATE_PCLK_I2C1)); #else cru_writel(CLK_GATE_W_MSK(CLK_GATE_PCLK_I2C0)|CLK_UN_GATE(CLK_GATE_PCLK_I2C0), CLK_GATE_CLKID_CONS(CLK_GATE_PCLK_I2C0)); #endif data[2] = readl_relaxed(RK2928_GRF_BASE + GRF_GPIO_IOMUX); writel_relaxed(data[2]| I2C_GRF_GPIO_IOMUX, RK2928_GRF_BASE + GRF_GPIO_IOMUX); div = 0x1e; divh = divl = 0xf; writel_relaxed(I2C_CLKDIV_VAL(divl, divh), SRAM_I2C_ADDRBASE + I2C_CLKDIV); data[3] = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CLKDIV); }