From patchwork Fri Mar 4 09:01:09 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 608161 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2491Xfr013906 for ; Fri, 4 Mar 2011 09:01:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759331Ab1CDJBk (ORCPT ); Fri, 4 Mar 2011 04:01:40 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:39223 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759307Ab1CDJBa (ORCPT ); Fri, 4 Mar 2011 04:01:30 -0500 Received: from eu_spt1 (mailout1.w1.samsung.com [210.118.77.11]) by mailout1.w1.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTP id <0LHI001UZZQEIV@mailout1.w1.samsung.com>; Fri, 04 Mar 2011 09:01:26 +0000 (GMT) Received: from linux.samsung.com ([106.116.38.10]) by spt1.w1.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTPA id <0LHI00HMRZQEEK@spt1.w1.samsung.com>; Fri, 04 Mar 2011 09:01:26 +0000 (GMT) Received: from localhost.localdomain (unknown [106.116.38.10]) by linux.samsung.com (Postfix) with ESMTP id E396B27005E; Fri, 04 Mar 2011 10:02:10 +0100 (CET) Date: Fri, 04 Mar 2011 10:01:09 +0100 From: Marek Szyprowski Subject: [PATCH 2/7] ARM: S5PV310: power domains: fixes and code cleanup In-reply-to: <1299229274-9753-1-git-send-email-m.szyprowski@samsung.com> To: linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Cc: m.szyprowski@samsung.com, kyungmin.park@samsung.com, kgene.kim@samsung.com, andrzej.p@samsung.com, t.stanislaws@samsung.com, s.nawrocki@samsung.com, k.debski@samsung.com Message-id: <1299229274-9753-3-git-send-email-m.szyprowski@samsung.com> MIME-version: 1.0 X-Mailer: git-send-email 1.7.2.3 Content-type: TEXT/PLAIN Content-transfer-encoding: 7BIT References: <1299229274-9753-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 04 Mar 2011 09:01:53 +0000 (UTC) diff --git a/arch/arm/mach-s5pv310/dev-pd.c b/arch/arm/mach-s5pv310/dev-pd.c index 58a50c2..e051998 100644 --- a/arch/arm/mach-s5pv310/dev-pd.c +++ b/arch/arm/mach-s5pv310/dev-pd.c @@ -16,13 +16,17 @@ #include #include +#include #include +static spinlock_t gate_block_slock = SPIN_LOCK_UNLOCKED; + static int s5pv310_pd_enable(struct device *dev) { struct samsung_pd_info *pdata = dev->platform_data; u32 timeout; + int ret = 0; __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base); @@ -31,21 +35,39 @@ static int s5pv310_pd_enable(struct device *dev) 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; + dev_err(dev, "enable failed\n"); + ret = -ETIMEDOUT; + goto done; } timeout--; udelay(100); } - return 0; + /* configure clk gate mask if it is present */ + if (pdata->gate_mask) { + unsigned long flags; + unsigned long value; + + spin_lock_irqsave(&gate_block_slock, flags); + + value = __raw_readl(S5P_CLKGATE_BLOCK); + value |= pdata->gate_mask; + __raw_writel(value, S5P_CLKGATE_BLOCK); + + spin_unlock_irqrestore(&gate_block_slock, flags); + } + +done: + dev_info(dev, "enable finished\n"); + + return ret; } static int s5pv310_pd_disable(struct device *dev) { struct samsung_pd_info *pdata = dev->platform_data; u32 timeout; + int ret = 0; __raw_writel(0, pdata->base); @@ -53,81 +75,108 @@ static int s5pv310_pd_disable(struct device *dev) timeout = 10; 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; + dev_err(dev, "disable failed\n"); + ret = -ETIMEDOUT; + goto done; } timeout--; udelay(100); } - return 0; + if (pdata->gate_mask) { + unsigned long flags; + unsigned long value; + + spin_lock_irqsave(&gate_block_slock, flags); + + value = __raw_readl(S5P_CLKGATE_BLOCK); + value &= ~pdata->gate_mask; + __raw_writel(value, S5P_CLKGATE_BLOCK); + + spin_unlock_irqrestore(&gate_block_slock, flags); + } +done: + dev_info(dev, "disable finished\n"); + + return ret; } struct platform_device s5pv310_device_pd[] = { - { + [PD_MFC] = { .name = "samsung-pd", - .id = 0, + .id = PD_MFC, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, .disable = s5pv310_pd_disable, .base = S5P_PMU_MFC_CONF, + .gate_mask = S5P_CLKGATE_BLOCK_MFC, }, }, - }, { + }, + [PD_G3D] = { .name = "samsung-pd", - .id = 1, + .id = PD_G3D, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, .disable = s5pv310_pd_disable, .base = S5P_PMU_G3D_CONF, + .gate_mask = S5P_CLKGATE_BLOCK_G3D, }, }, - }, { + }, + [PD_LCD0] = { .name = "samsung-pd", - .id = 2, + .id = PD_LCD0, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, .disable = s5pv310_pd_disable, .base = S5P_PMU_LCD0_CONF, + .gate_mask = S5P_CLKGATE_BLOCK_LCD0, }, }, - }, { + }, + [PD_LCD1] = { .name = "samsung-pd", - .id = 3, + .id = PD_LCD1, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, .disable = s5pv310_pd_disable, .base = S5P_PMU_LCD1_CONF, + .gate_mask = S5P_CLKGATE_BLOCK_LCD1, }, }, - }, { + }, + [PD_TV] = { .name = "samsung-pd", - .id = 4, + .id = PD_TV, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, .disable = s5pv310_pd_disable, .base = S5P_PMU_TV_CONF, + .gate_mask = S5P_CLKGATE_BLOCK_TV, }, }, - }, { + }, + [PD_CAM] = { .name = "samsung-pd", - .id = 5, + .id = PD_CAM, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, .disable = s5pv310_pd_disable, .base = S5P_PMU_CAM_CONF, + .gate_mask = S5P_CLKGATE_BLOCK_CAM, }, }, - }, { + }, + [PD_GPS] = { .name = "samsung-pd", - .id = 6, + .id = PD_GPS, .dev = { .platform_data = &(struct samsung_pd_info) { .enable = s5pv310_pd_enable, diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h index b5c4ada..341571a 100644 --- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h @@ -73,6 +73,7 @@ #define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940) #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) #define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960) +#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x0C970) #define S5P_CLKSRC_DMC S5P_CLKREG(0x10200) #define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500) @@ -160,6 +161,14 @@ #define S5P_CLKDIV_BUS_GPLR_SHIFT (4) #define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT) +/* CLKGATE_BLOCK */ +#define S5P_CLKGATE_BLOCK_CAM (1 << 0) +#define S5P_CLKGATE_BLOCK_TV (1 << 1) +#define S5P_CLKGATE_BLOCK_MFC (1 << 2) +#define S5P_CLKGATE_BLOCK_G3D (1 << 3) +#define S5P_CLKGATE_BLOCK_LCD0 (1 << 4) +#define S5P_CLKGATE_BLOCK_LCD1 (1 << 5) + /* Compatibility defines */ #define S5P_EPLL_CON S5P_EPLL_CON0 diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h index 5f0ad85..36ba851 100644 --- a/arch/arm/plat-samsung/include/plat/pd.h +++ b/arch/arm/plat-samsung/include/plat/pd.h @@ -15,6 +15,7 @@ struct samsung_pd_info { int (*enable)(struct device *dev); int (*disable)(struct device *dev); void __iomem *base; + unsigned long gate_mask; }; enum s5pv310_pd_block {