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;
}
예제 #2
0
static u32 spdif_clk_enter()
{
  u32 clk = cru_readl(CRU_CLKSEL5_CON);
  cru_writel(0x1ffff, CRU_CLKSEL5_CON);
  mdelay(1);
  return clk;
}
예제 #3
0
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);
}
예제 #4
0
/* 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);
	}
}
예제 #5
0
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();
}
예제 #6
0
파일: rk3288.c 프로젝트: Astralix/kernel
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;
             
}
예제 #7
0
/* 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;
	}
}
예제 #8
0
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);
}
예제 #10
0
/* 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));
	}
}
예제 #11
0
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);
}