From c6da2cfeb05178a11c6d062a06f8078150ee492f Mon Sep 17 00:00:00 2001 From: codeworkx Date: Sat, 2 Jun 2012 13:09:29 +0200 Subject: samsung update 1 --- arch/arm/mach-exynos/dev-pd.c | 167 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 arch/arm/mach-exynos/dev-pd.c (limited to 'arch/arm/mach-exynos/dev-pd.c') diff --git a/arch/arm/mach-exynos/dev-pd.c b/arch/arm/mach-exynos/dev-pd.c new file mode 100644 index 0000000..2441fe6 --- /dev/null +++ b/arch/arm/mach-exynos/dev-pd.c @@ -0,0 +1,167 @@ +/* linux/arch/arm/mach-exynos/dev-pd.c + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * EXYNOS4 - Power Domain support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +int exynos_pd_init(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + struct exynos_pd_data *data = (struct exynos_pd_data *) pdata->data; + + if (soc_is_exynos4210() && data->read_phy_addr) { + data->read_base = ioremap(data->read_phy_addr, SZ_4K); + if (!data->read_base) + return -ENOMEM; + } + + return 0; +} + +int exynos_pd_enable(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + struct exynos_pd_data *data = (struct exynos_pd_data *) pdata->data; + u32 timeout; + u32 tmp = 0; + + /* save IP clock gating register */ + if (data->clk_base) { + tmp = __raw_readl(data->clk_base); + + /* enable all the clocks of IPs in the power domain */ + __raw_writel(0xffffffff, data->clk_base); + } + + __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base); + + /* Wait max 1ms */ + timeout = 1000; + while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) + != S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + printk(KERN_ERR "Power domain %s enable failed.\n", + dev_name(dev)); + return -ETIMEDOUT; + } + timeout--; + udelay(1); + } + + if (data->read_base) + /* dummy read to check the completion of power-on sequence */ + __raw_readl(data->read_base); + + /* restore IP clock gating register */ + if (data->clk_base) + __raw_writel(tmp, data->clk_base); + + bts_enable(pdata->id); + return 0; +} + +int exynos_pd_disable(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + struct exynos_pd_data *data = (struct exynos_pd_data *) pdata->data; + u32 timeout; + u32 tmp = 0; + + static int boot_lcd0 = 1; + if (boot_lcd0) { + struct platform_device *pdev = to_platform_device(dev); + /* + * Currently,in exynos4x12, FIMD parent power domain + * is PD_LCD0, + * but in exynos5x12, it is changed to PD_DISP1. + * so i add PD_DISP1 for exynos5 + */ + if ((pdev->id == PD_LCD0) || (pdev->id == PD_DISP1)) { + printk(KERN_INFO "lcd0 disable skip only one time"); + boot_lcd0--; + return 0; + } + } + + /* save clock source register */ + if (data->clksrc_base) + tmp = __raw_readl(data->clksrc_base); +#ifdef CONFIG_EXYNOS5_LOWPWR_IDLE + if (soc_is_exynos5250() && + (pdata->base == EXYNOS5_ISP_CONFIGURATION)) + return 0; +#endif + /* Do not disable MFC power domain for EXYNOS5250 EVT0 */ + if (soc_is_exynos5250() && + (samsung_rev() < EXYNOS5250_REV_1_0) && + (pdata->base == EXYNOS5_MFC_CONFIGURATION)) + return 0; + + /* + * To ISP power domain off, + * first, ISP_ARM power domain be off. + */ + if (soc_is_exynos5250() && + (pdata->base == EXYNOS5_ISP_CONFIGURATION)) { + if (!(__raw_readl(EXYNOS5_ISP_ARM_STATUS) & 0x1)) { + /* Disable ISP_ARM */ + timeout = __raw_readl(EXYNOS5_ISP_ARM_OPTION); + timeout &= ~EXYNOS5_ISP_ARM_ENABLE; + __raw_writel(timeout, EXYNOS5_ISP_ARM_OPTION); + + /* ISP_ARM power off */ + __raw_writel(0x0, EXYNOS5_ISP_ARM_CONFIGURATION); + + timeout = 1000; + + while (__raw_readl(EXYNOS5_ISP_ARM_STATUS) & 0x1) { + if (timeout == 0) { + printk(KERN_ERR "ISP_ARM power domain can not off\n"); + return -ETIMEDOUT; + } + timeout--; + udelay(1); + } + /* CMU_RESET_ISP_ARM off */ + __raw_writel(0x0, EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG); + } + } + + __raw_writel(0, pdata->base); + + /* Wait max 1ms */ + timeout = 1000; + while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + printk(KERN_ERR "Power domain %s disable failed.\n", + dev_name(dev)); + return -ETIMEDOUT; + } + timeout--; + udelay(1); + } + + /* restore clock source register */ + if (data->clksrc_base) + __raw_writel(tmp, data->clksrc_base); + return 0; +} -- cgit v1.1