From patchwork Wed Oct 15 17:23:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kever Yang X-Patchwork-Id: 5086471 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4F190C11AD for ; Wed, 15 Oct 2014 17:26:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 519812013A for ; Wed, 15 Oct 2014 17:26:14 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 402122012E for ; Wed, 15 Oct 2014 17:26:13 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XeSIv-0006Ne-Bq; Wed, 15 Oct 2014 17:24:05 +0000 Received: from mail-pa0-x22f.google.com ([2607:f8b0:400e:c03::22f]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XeSIZ-0006E0-2t; Wed, 15 Oct 2014 17:23:43 +0000 Received: by mail-pa0-f47.google.com with SMTP id rd3so1683230pab.34 for ; Wed, 15 Oct 2014 10:23:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=hrq7M90wKh8TkurDltAd+BVZJYhGr3lq1D2dlNTBGlU=; b=FUKPef8s3Fir86GX85yU7qkzHMjICW/ZqRRtF4lYIkHKaqTSDxdjyQ52RZz9P7mXQJ zESXtL9FWWFRM2n0hWsw8mMHVWCeiMyarAKQB4bXHr3JMAz2L9pdUUL1iGpHtl//Kr6M zbKxSJfYMBEPaqSaiajd4EwM0ONn+wIp48GFWPUQ0KyXrPwxdZRfrRRBE1KmyOhpZtZk ha9QqJC+6DjAcwIKAUMot/Q9EoXrp7tf9TdYs1amt23K8CTFC5Nh3lHhp7Gz9BCcRgJV 3zIdMM2OSUnWKU0mvirnAFCEf2DaLIcXjaBFr5jk79PvOq7xuWAm2ljgmjOkzzbmG9OV 9Otw== X-Received: by 10.68.232.233 with SMTP id tr9mr14186700pbc.52.1413393801602; Wed, 15 Oct 2014 10:23:21 -0700 (PDT) Received: from kever-X240.corp.google.com (dhcp-172-22-52-129.mtv.corp.google.com [172.22.52.129]) by mx.google.com with ESMTPSA id zw1sm14760882pbb.82.2014.10.15.10.23.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 15 Oct 2014 10:23:21 -0700 (PDT) From: Kever Yang To: heiko@sntech.de Subject: [PATCH v5 1/6] ARM: rockchip: convert to regmap and use pmu syscon if available Date: Wed, 15 Oct 2014 10:23:00 -0700 Message-Id: <1413393785-26783-2-git-send-email-kever.yang@rock-chips.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1413393785-26783-1-git-send-email-kever.yang@rock-chips.com> References: <1413393785-26783-1-git-send-email-kever.yang@rock-chips.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141015_102343_176658_C4E5335C X-CRM114-Status: GOOD ( 19.89 ) X-Spam-Score: -0.7 (/) Cc: huangtao@rock-chips.com, addy.ke@rock-chips.com, Russell King , linux-kernel@vger.kernel.org, dianders@chromium.org, Kever Yang , linux-rockchip@lists.infradead.org, xjq@rock-chips.com, cf@rock-chips.com, hj@rock-chips.com, sonnyrao@chromium.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Heiko Stuebner The pmu register space is - like the GRF - shared by quite some peripherals. On the rk3188 and rk3288 even parts of the pinctrl are living there. Therefore we normally shouldn't map it a second time when the syscon does this already. Therefore convert the cpu power-domain handling to access the pmu via a regmap and at first try to get it via the syscon interface. Getting this syscon will only fail if the pmu node does not have the "syscon" compatible and thus does not get shared with other drivers. In this case we map it like before and create the necessary regmap on top of it. Signed-off-by: Heiko Stuebner Signed-off-by: Kever Yang --- Changes in v5: None Changes in v4: None Changes in v3: - add this patch in version 3 Changes in v2: None arch/arm/mach-rockchip/platsmp.c | 104 +++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 189684f..4c36fbf 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -37,23 +39,42 @@ static int ncores; #define PMU_PWRDN_SCU 4 -static void __iomem *pmu_base_addr; +static struct regmap *pmu; -static inline bool pmu_power_domain_is_on(int pd) +static int pmu_power_domain_is_on(int pd) { - return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd)); + u32 val; + int ret; + + ret = regmap_read(pmu, PMU_PWRDN_ST, &val); + if (ret < 0) + return ret; + + return !(val & BIT(pd)); } -static void pmu_set_power_domain(int pd, bool on) +static int pmu_set_power_domain(int pd, bool on) { - u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON); - if (on) - val &= ~BIT(pd); - else - val |= BIT(pd); - writel(val, pmu_base_addr + PMU_PWRDN_CON); - - while (pmu_power_domain_is_on(pd) != on) { } + u32 val = (on) ? 0 : BIT(pd); + int ret; + + ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val); + if (ret < 0) { + pr_err("%s: could not update power domain\n", __func__); + return ret; + } + + ret = -1; + while (ret != on) { + ret = pmu_power_domain_is_on(pd); + if (ret < 0) { + pr_err("%s: could not read power domain state\n", + __func__); + return ret; + } + } + + return 0; } /* @@ -63,7 +84,7 @@ static void pmu_set_power_domain(int pd, bool on) static int __cpuinit rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle) { - if (!sram_base_addr || !pmu_base_addr) { + if (!sram_base_addr || !pmu) { pr_err("%s: sram or pmu missing for cpu boot\n", __func__); return -ENXIO; } @@ -75,9 +96,7 @@ static int __cpuinit rockchip_boot_secondary(unsigned int cpu, } /* start the core */ - pmu_set_power_domain(0 + cpu, true); - - return 0; + return pmu_set_power_domain(0 + cpu, true); } /** @@ -125,6 +144,48 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node) return 0; } +static struct regmap_config rockchip_pmu_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static int __init rockchip_smp_prepare_pmu(void) +{ + struct device_node *node; + void __iomem *pmu_base; + + pmu = syscon_regmap_lookup_by_compatible("rockchip,rk3066-pmu"); + if (!IS_ERR(pmu)) + return 0; + + /* fallback, create our own regmap for the pmu area */ + pmu = NULL; + node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); + if (!node) { + pr_err("%s: could not find pmu dt node\n", __func__); + return -ENODEV; + } + + pmu_base = of_iomap(node, 0); + if (!pmu_base) { + pr_err("%s: could not map pmu registers\n", __func__); + return -ENOMEM; + } + + pmu = regmap_init_mmio(NULL, pmu_base, &rockchip_pmu_regmap_config); + if (IS_ERR(pmu)) { + int ret = PTR_ERR(pmu); + + iounmap(pmu_base); + pmu = NULL; + pr_err("%s: regmap init failed\n", __func__); + return ret; + } + + return 0; +} + static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) { struct device_node *node; @@ -151,17 +212,8 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) if (rockchip_smp_prepare_sram(node)) return; - node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); - if (!node) { - pr_err("%s: could not find pmu dt node\n", __func__); + if (rockchip_smp_prepare_pmu()) return; - } - - pmu_base_addr = of_iomap(node, 0); - if (!pmu_base_addr) { - pr_err("%s: could not map pmu registers\n", __func__); - return; - } /* enable the SCU power domain */ pmu_set_power_domain(PMU_PWRDN_SCU, true);