Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp3140577pxa; Tue, 18 Aug 2020 07:38:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw/7durq7Cb8A47alz+15zeiXbt26UxhSQrshXXeGXoBSCI8CyAx5Ru7nf6OUPS+3INPnRK X-Received: by 2002:a05:6402:3196:: with SMTP id di22mr19643376edb.193.1597761497115; Tue, 18 Aug 2020 07:38:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597761497; cv=none; d=google.com; s=arc-20160816; b=WMhgjdz4dHr/n63YHmftkNEShkF17WpwTxjhAR/hEcoAANB66B7dZ0E9u/QE9iX1rk RXNb0zAgxzgGtmMmwyy/flW+pX6ywerDsSRBN0hlzeyjAvZMeUYQ9CisdcVpSIJFx45N ZnIpBK6uggDBGdhVdGNOwZWcfnyu6DJbee+p9ooH6hwEuAyQ9QzzWxDkdGn22TsffDHK A8GFSplWgQqWq5DF3j47UZ75lKuyoZ71ZywR/TSJteKeQy4UzL3fNMsHn7/I+IKN2OIa rundoQ7gQF3h/2HGtWYk+EDJiM6/prPwfKYmctpz1lFFKcgfUBvwKS6Dn6w9698eUpAS +eFw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:ironport-sdr:ironport-sdr; bh=ytQw7yhUQ7WuzMTI5JbgycDjjrPe0JS4+KjVSu3IFeM=; b=xDSrxUGI438P2RZzCfIFNgDNi2lW7nMRQPfbCtm18O+ZCohXCZbaPMuItC25odfGeC klewuJrW+Ecse2yoLRwDRKVmfka6M8A73Df0cU4HIyGSUiLnVZQNF45HXqixTZNZhlMK jGVMddMq/g6A22UOjRLTSVqvSlCK6Fu8B/X9bSjigaRWyNUuiRhshr8E/AWdR/u+q7NW 2aOWS1bzb5Qv70ajp/Cigl6UiboO7A8U1FoxewFb/UnRS7REUfmcIqT8AHwqxdxthqJR KMvrjAtz6AYAnAYmr9Bd0GoDAHpNKeRYWgGKi8k7df+POobV6tj1q4udQXb8zstHoP5h M4Qg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u24si12893946edx.408.2020.08.18.07.37.53; Tue, 18 Aug 2020 07:38:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726585AbgHROgE (ORCPT + 99 others); Tue, 18 Aug 2020 10:36:04 -0400 Received: from mga14.intel.com ([192.55.52.115]:33372 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727782AbgHROgA (ORCPT ); Tue, 18 Aug 2020 10:36:00 -0400 IronPort-SDR: /IB+J/pI3uKRLLl5XM2o3Gu6g0zjpz5uKOsihL9ijLdmI43UPRfCZ4wO5KMfg8Ja3oRyD2toSk Ycw4uvlM7QNA== X-IronPort-AV: E=McAfee;i="6000,8403,9716"; a="154170594" X-IronPort-AV: E=Sophos;i="5.76,327,1592895600"; d="scan'208";a="154170594" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Aug 2020 07:35:58 -0700 IronPort-SDR: pYASlFNwMd+E6GmvVY2K0hPj6X6RBKwWRPIgbELDlzpSI8BP2Gv2bFjzeOhMIX99aZ3keJVKEq bIv23cQ8RUSw== X-IronPort-AV: E=Sophos;i="5.76,327,1592895600"; d="scan'208";a="471830800" Received: from bard-ubuntu.sh.intel.com ([10.239.13.33]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Aug 2020 07:35:54 -0700 From: Bard Liao To: alsa-devel@alsa-project.org, vkoul@kernel.org Cc: vinod.koul@linaro.org, linux-kernel@vger.kernel.org, tiwai@suse.de, broonie@kernel.org, gregkh@linuxfoundation.org, jank@cadence.com, srinivas.kandagatla@linaro.org, rander.wang@linux.intel.com, ranjani.sridharan@linux.intel.com, hui.wang@canonical.com, pierre-louis.bossart@linux.intel.com, sanyog.r.kale@intel.com, mengdong.lin@intel.com, bard.liao@intel.com Subject: [PATCH 11/11] soundwire: intel: don't manage link power individually Date: Tue, 18 Aug 2020 10:41:20 +0800 Message-Id: <20200818024120.20721-12-yung-chuan.liao@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200818024120.20721-1-yung-chuan.liao@linux.intel.com> References: <20200818024120.20721-1-yung-chuan.liao@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pierre-Louis Bossart Each link has separate power controls, but experimental results show we need to use an all-or-none approach to the link power management. This change has marginal power impacts, the DSP needs to be powered anyways before SoundWire links can be powered, and even when powered a link can be in clock-stopped mode. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Bard Liao --- drivers/soundwire/intel.c | 70 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index b82d02af3c4f..154aa7c0561a 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -63,7 +63,9 @@ MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off #define SDW_SHIM_WAKESTS 0x192 #define SDW_SHIM_LCTL_SPA BIT(0) +#define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0) #define SDW_SHIM_LCTL_CPA BIT(8) +#define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8) #define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1) #define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1) @@ -295,8 +297,8 @@ static int intel_link_power_up(struct sdw_intel *sdw) u32 *shim_mask = sdw->link_res->shim_mask; struct sdw_bus *bus = &sdw->cdns.bus; struct sdw_master_prop *prop = &bus->prop; - int spa_mask, cpa_mask; - int link_control; + u32 spa_mask, cpa_mask; + u32 link_control; int ret = 0; u32 syncprd; u32 sync_reg; @@ -319,6 +321,8 @@ static int intel_link_power_up(struct sdw_intel *sdw) syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24; if (!*shim_mask) { + dev_dbg(sdw->cdns.dev, "%s: powering up all links\n", __func__); + /* we first need to program the SyncPRD/CPU registers */ dev_dbg(sdw->cdns.dev, "%s: first link up, programming SYNCPRD\n", __func__); @@ -331,21 +335,24 @@ static int intel_link_power_up(struct sdw_intel *sdw) /* Set SyncCPU bit */ sync_reg |= SDW_SHIM_SYNC_SYNCCPU; intel_writel(shim, SDW_SHIM_SYNC, sync_reg); - } - /* Link power up sequence */ - link_control = intel_readl(shim, SDW_SHIM_LCTL); - spa_mask = (SDW_SHIM_LCTL_SPA << link_id); - cpa_mask = (SDW_SHIM_LCTL_CPA << link_id); - link_control |= spa_mask; + /* Link power up sequence */ + link_control = intel_readl(shim, SDW_SHIM_LCTL); - ret = intel_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask); - if (ret < 0) { - dev_err(sdw->cdns.dev, "Failed to power up link: %d\n", ret); - goto out; - } + /* only power-up enabled links */ + spa_mask = sdw->link_res->link_mask << + SDW_REG_SHIFT(SDW_SHIM_LCTL_SPA_MASK); + cpa_mask = sdw->link_res->link_mask << + SDW_REG_SHIFT(SDW_SHIM_LCTL_CPA_MASK); + + link_control |= spa_mask; + + ret = intel_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask); + if (ret < 0) { + dev_err(sdw->cdns.dev, "Failed to power up link: %d\n", ret); + goto out; + } - if (!*shim_mask) { /* SyncCPU will change once link is active */ ret = intel_wait_bit(shim, SDW_SHIM_SYNC, SDW_SHIM_SYNC_SYNCCPU, 0); @@ -483,7 +490,7 @@ static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable) static int intel_link_power_down(struct sdw_intel *sdw) { - int link_control, spa_mask, cpa_mask; + u32 link_control, spa_mask, cpa_mask; unsigned int link_id = sdw->instance; void __iomem *shim = sdw->link_res->shim; u32 *shim_mask = sdw->link_res->shim_mask; @@ -493,24 +500,39 @@ static int intel_link_power_down(struct sdw_intel *sdw) intel_shim_master_ip_to_glue(sdw); - /* Link power down sequence */ - link_control = intel_readl(shim, SDW_SHIM_LCTL); - spa_mask = ~(SDW_SHIM_LCTL_SPA << link_id); - cpa_mask = (SDW_SHIM_LCTL_CPA << link_id); - link_control &= spa_mask; - - ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask); - if (!(*shim_mask & BIT(link_id))) dev_err(sdw->cdns.dev, "%s: Unbalanced power-up/down calls\n", __func__); *shim_mask &= ~BIT(link_id); + if (!*shim_mask) { + + dev_dbg(sdw->cdns.dev, "%s: powering down all links\n", __func__); + + /* Link power down sequence */ + link_control = intel_readl(shim, SDW_SHIM_LCTL); + + /* only power-down enabled links */ + spa_mask = (~sdw->link_res->link_mask) << + SDW_REG_SHIFT(SDW_SHIM_LCTL_SPA_MASK); + cpa_mask = sdw->link_res->link_mask << + SDW_REG_SHIFT(SDW_SHIM_LCTL_CPA_MASK); + + link_control &= spa_mask; + + ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask); + } + + link_control = intel_readl(shim, SDW_SHIM_LCTL); + mutex_unlock(sdw->link_res->shim_lock); - if (ret < 0) + if (ret < 0) { + dev_err(sdw->cdns.dev, "%s: could not power down link\n", __func__); + return ret; + } sdw->cdns.link_up = false; return 0; -- 2.17.1