From patchwork Sat Jun 27 03:02:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 50394 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f72.google.com (mail-wg0-f72.google.com [74.125.82.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B8F56228FD for ; Sat, 27 Jun 2015 03:03:22 +0000 (UTC) Received: by wgjx7 with SMTP id x7sf9467690wgj.3 for ; Fri, 26 Jun 2015 20:03:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=BRsF2UgT9FCLT1W3Pd0ao8Jk3id3Iw4oMk0t0ritJTg=; b=UCyfoVqlOfbXsutai3laqxw4+ko8taXDhyU3FiEgqLjbxqJAmSflHO+uM9AYK4CsUM qtEtXTXyL4kZXVPf3alDCq7FfSafwmphpSzfjfp4zunQdvlqVHZ9RlLtdHoRRno/TxSQ c9DxM7RaMc9LnIbBL2ySm4k+qCUBEOjvEdENb+kBzApQQo4aNeppnZTOyy7s+emvfyLc S3T8LA6MXsWU4mnsJCntJZ/2HEgxVxQGZgFE92HX5GC9+SbWYxqatZG6CmXJ6PPTeJN3 vn+IyZH5llsVjq44hhFCCpren2bvFnXnMCIWL5XtrXhvTO7D3ddKSgVIJDcBzZ7l72uA sR3Q== X-Gm-Message-State: ALoCoQlfD6nzAzYjTTg+/KbI8v5Hh26noE4NzhM7x6D7VaNeDBbdf5+DrnFwAXRAqmfviyl6HIgz X-Received: by 10.180.105.226 with SMTP id gp2mr913149wib.1.1435374202048; Fri, 26 Jun 2015 20:03:22 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.120.227 with SMTP id lf3ls596816lab.93.gmail; Fri, 26 Jun 2015 20:03:21 -0700 (PDT) X-Received: by 10.112.212.9 with SMTP id ng9mr4323520lbc.57.1435374201756; Fri, 26 Jun 2015 20:03:21 -0700 (PDT) Received: from mail-la0-f51.google.com (mail-la0-f51.google.com. [209.85.215.51]) by mx.google.com with ESMTPS id pl9si28980708lbb.111.2015.06.26.20.03.21 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Jun 2015 20:03:21 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) client-ip=209.85.215.51; Received: by lagx9 with SMTP id x9so74575225lag.1 for ; Fri, 26 Jun 2015 20:03:21 -0700 (PDT) X-Received: by 10.152.6.69 with SMTP id y5mr4303299lay.72.1435374201648; Fri, 26 Jun 2015 20:03:21 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp295292lbb; Fri, 26 Jun 2015 20:03:20 -0700 (PDT) X-Received: by 10.68.238.39 with SMTP id vh7mr9477779pbc.12.1435374185949; Fri, 26 Jun 2015 20:03:05 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ay3si53186466pbc.54.2015.06.26.20.03.05; Fri, 26 Jun 2015 20:03:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752660AbbF0DDE (ORCPT + 11 others); Fri, 26 Jun 2015 23:03:04 -0400 Received: from mail-pd0-f178.google.com ([209.85.192.178]:34951 "EHLO mail-pd0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751732AbbF0DDB (ORCPT ); Fri, 26 Jun 2015 23:03:01 -0400 Received: by pdbci14 with SMTP id ci14so84811006pdb.2 for ; Fri, 26 Jun 2015 20:03:01 -0700 (PDT) X-Received: by 10.66.250.12 with SMTP id yy12mr9217993pac.43.1435374181141; Fri, 26 Jun 2015 20:03:01 -0700 (PDT) Received: from ubuntu.localdomain (c-24-8-37-141.hsd1.co.comcast.net. [24.8.37.141]) by mx.google.com with ESMTPSA id j7sm34787756pdp.83.2015.06.26.20.02.59 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jun 2015 20:03:00 -0700 (PDT) From: Lina Iyer To: rjw@rjwysocki.net, ulf.hansson@linaro.org, khilman@linaro.org Cc: geert@linux-m68k.org, k.kozlowski@samsung.com, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, msivasub@codeaurora.org, agross@codeaurora.org, Lina Iyer Subject: [PATCH RFC v2 11/16] drivers: qcom: spm: Support cache and coherency SPMs Date: Fri, 26 Jun 2015 21:02:31 -0600 Message-Id: <1435374156-19214-12-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1435374156-19214-1-git-send-email-lina.iyer@linaro.org> References: <1435374156-19214-1-git-send-email-lina.iyer@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lina.iyer@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Recognize non-CPU SPM devices defined in the DT and configure the corresponding SPM hardware. SPM controllers for L2 controls the cache's idle low power state and may also be used to turn off the cluster's power rail. On multi-cluster SoCs, each cluster would have an SPM for the cache and an additional coherency level SPM. The coherency SPM turns off or puts the coherency hardware in idle and any caches present at that level. Signed-off-by: Lina Iyer --- drivers/soc/qcom/spm.c | 75 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c index b04b05a..bef2dfe1 100644 --- a/drivers/soc/qcom/spm.c +++ b/drivers/soc/qcom/spm.c @@ -68,9 +68,17 @@ struct spm_reg_data { u8 start_index[PM_SLEEP_MODE_NR]; }; +struct cluster; + struct spm_driver_data { void __iomem *reg_base; const struct spm_reg_data *reg_data; + struct cluster *domain; +}; + +/* Group for domain entities */ +struct cluster { + struct spm_driver_data *domain_spm; }; static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = { @@ -116,6 +124,9 @@ static const struct spm_reg_data spm_reg_8064_cpu = { static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv); +/* 3 instances: little, big and coherency (cluster of clusters) */ +static struct cluster cpu_domain[3]; + typedef int (*idle_fn)(int); static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops); @@ -282,14 +293,26 @@ static struct cpuidle_ops qcom_cpuidle_ops __initdata = { CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v1, "qcom,kpss-acc-v1", &qcom_cpuidle_ops); CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v2, "qcom,kpss-acc-v2", &qcom_cpuidle_ops); +/* Match L2 SPM with their affinity level */ +static const struct of_device_id cache_spm_table[] = { + { }, +}; + static struct spm_driver_data *spm_get_drv(struct platform_device *pdev, - int *spm_cpu) + int *index, bool *is_domain_spm) { struct spm_driver_data *drv = NULL; - struct device_node *cpu_node, *saw_node; + struct device_node *cpu_node, *saw_node, *cache_node; int cpu; bool found; + const struct of_device_id *match_id; + int idx; + drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); + if (!drv) + return ERR_PTR(-ENOMEM); + + /* Check for a CPU SPM, if found we are done */ for_each_possible_cpu(cpu) { cpu_node = of_cpu_device_node_get(cpu); if (!cpu_node) @@ -302,10 +325,37 @@ static struct spm_driver_data *spm_get_drv(struct platform_device *pdev, break; } + /* + * If found, we have a CPU SPM, if not, + * check if we have a cache SPM + */ if (found) { - drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); - if (drv) - *spm_cpu = cpu; + /* + * Now that we have our CPU, find the associated L2 + * SAW and bind the CPU with the domain that contains + * the L2 SAW. + */ + cache_node = of_parse_phandle(cpu_node, + "next-level-cache", 0); + saw_node = of_parse_phandle(cache_node, "qcom,saw", 0); + match_id = of_match_node(cache_spm_table, saw_node); + if (match_id) { + idx = (int) match_id->data; + drv->domain = &cpu_domain[idx]; + } + of_node_put(saw_node); + of_node_put(cache_node); + *index = cpu; + *is_domain_spm = false; + } else { + /* Check if this is a cache SPM */ + match_id = of_match_node(cache_spm_table, pdev->dev.of_node); + if (!match_id) { + devm_kfree(&pdev->dev, drv); + return ERR_PTR(-ENODEV); + } + *index = (int) match_id->data; + *is_domain_spm = true; } return drv; @@ -327,11 +377,12 @@ static int spm_dev_probe(struct platform_device *pdev) struct resource *res; const struct of_device_id *match_id; void __iomem *addr; - int cpu; + int index; + bool is_domain_spm; - drv = spm_get_drv(pdev, &cpu); - if (!drv) - return -EINVAL; + drv = spm_get_drv(pdev, &index, &is_domain_spm); + if (IS_ERR(drv)) + return PTR_ERR(drv); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); drv->reg_base = devm_ioremap_resource(&pdev->dev, res); @@ -366,7 +417,11 @@ static int spm_dev_probe(struct platform_device *pdev) /* Set up Standby as the default low power mode */ spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY); - per_cpu(cpu_spm_drv, cpu) = drv; + /* We are ready to use the CPU/Cache SPM. */ + if (is_domain_spm) + cpu_domain[index].domain_spm = drv; + else + per_cpu(cpu_spm_drv, index) = drv; return 0; }