Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp851280pxk; Thu, 17 Sep 2020 19:03:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwPeAF9FNk5RfOHz93LJr9b64NkyQU209sWL0ghxLN1wzR71NIMh1qCDMd30OdC7gXXB4XG X-Received: by 2002:a17:906:488d:: with SMTP id v13mr33192174ejq.524.1600394611331; Thu, 17 Sep 2020 19:03:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600394611; cv=none; d=google.com; s=arc-20160816; b=QWd0prZImc42eIa6x2K99K7RG4ynG7XT5Qstawlbc61V/TPjeYXIoxUtgP8rMkANwG /rp2lhOpCMQqHyJvtYRkD8Za/QXjZubGu2v5L5RCM8LZo9eSieSAb2uhxxpBpPtPdEFr 1t1bdBx/o58RlLi3WRgic3Ph5RVtDPXyqHv1tWdtZyQcn+JNcRHfjCzkzsufu2XPl5bC hn+sGCDnWR9M9ssuQ1BgRRJPQkS1vW2mwRkVdkUfP7feKsRc9UICcFKEfBcsUhrhoa5D qamfgSOzra7tYBtJv8VVeGLQws8S+H/0UHdJ4/l4zMPARk4mlr3OSJwM1MP3SCBMH3+8 7SHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=uiSV4SJsnluyAFxb/5Cknyz+wHbsB+d4fdY1+jBsXw0=; b=T3dgVKHvdvAUnAx77vcIlPxYBTtwE05TodpmYuLumeXwLEHiJ7YGV29eXLBMryrzjM x+zehckNu+1xVExmRKvSyjLHoU73rJeBMjRFRsGDlXcvgDFxgJ+gBHPFjL2MUQO9X9lF QAbxPwO57nr6r6OwYoFcTOZ0Ip8F8bAvF/hZbsZSxwW/+XblfJMo3YTKcEnyeTAmtHK5 Tle1GQPAPll5S/vW+QmrZJuTPF45S7/UXOkGVaUEKEOEUJVR14tnvcUX5j9ftNsBGAMG RI2hRsF+Y6mddojxvA3A63/fg87caOY+gDbR0J//PP7dCcq14ZGAG+IAEMRApkY99cLK bDxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="i/muc9gS"; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r25si1063139edy.478.2020.09.17.19.03.07; Thu, 17 Sep 2020 19:03:31 -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; dkim=pass header.i=@kernel.org header.s=default header.b="i/muc9gS"; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726485AbgIRCBp (ORCPT + 99 others); Thu, 17 Sep 2020 22:01:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:46050 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726448AbgIRCBg (ORCPT ); Thu, 17 Sep 2020 22:01:36 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id BCFF921582; Fri, 18 Sep 2020 02:01:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1600394495; bh=h4jvZUa1Ribuy7hAiZfDjtbViMR4k27vIBMM2q+w2xQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i/muc9gSJ+4Jz0UkVcFzQfoa3VGe5Smu6120zjfc9lCmHKyQUkIkh2n0+wZ30mPYz ekCniBX8JBxx9C+iRcMtzbMDAB+Gv+doRBBSpLAwWW+Rg5gAbhAAkTs12Nw8a+o+1e mvusnvfv1TVkPerDkSKWmUXapMYZdmhbxTjg5GGU= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Pierre-Louis Bossart , Vinod Koul , Sasha Levin Subject: [PATCH AUTOSEL 5.4 020/330] soundwire: intel/cadence: fix startup sequence Date: Thu, 17 Sep 2020 21:56:00 -0400 Message-Id: <20200918020110.2063155-20-sashal@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200918020110.2063155-1-sashal@kernel.org> References: <20200918020110.2063155-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pierre-Louis Bossart [ Upstream commit 49ea07d33d9a32c17e18b322e789507280ceb2a3 ] Multiple changes squashed in single patch to avoid tick-tock effect and avoid breaking compilation/bisect 1. Per the hardware documentation, all changes to MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL need to be validated with a self-clearing write to MCP_CONFIG_UPDATE. Add a helper and do the update when the CONFIG is changed. 2. Move interrupt enable after interrupt handler registration 3. Add a new helper to start the hardware bus reset with maximum duration to make sure the Slave(s) correctly detect the reset pattern and to ensure electrical conflicts can be resolved. 4. flush command FIFOs Better error handling will be provided after interrupt disable is provided in follow-up patches. Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191022235448.17586-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/soundwire/cadence_master.c | 80 +++++++++++++++++++++--------- drivers/soundwire/cadence_master.h | 1 + drivers/soundwire/intel.c | 14 +++++- 3 files changed, 69 insertions(+), 26 deletions(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 502ed4ec8f070..e3d06330d1258 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -231,6 +231,22 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value) return -EAGAIN; } +/* + * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL + * need to be confirmed with a write to MCP_CONFIG_UPDATE + */ +static int cdns_update_config(struct sdw_cdns *cdns) +{ + int ret; + + ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE, + CDNS_MCP_CONFIG_UPDATE_BIT); + if (ret < 0) + dev_err(cdns->dev, "Config update timedout\n"); + + return ret; +} + /* * debugfs */ @@ -752,7 +768,38 @@ EXPORT_SYMBOL(sdw_cdns_thread); /* * init routines */ -static int _cdns_enable_interrupt(struct sdw_cdns *cdns) + +/** + * sdw_cdns_exit_reset() - Program reset parameters and start bus operations + * @cdns: Cadence instance + */ +int sdw_cdns_exit_reset(struct sdw_cdns *cdns) +{ + /* program maximum length reset to be safe */ + cdns_updatel(cdns, CDNS_MCP_CONTROL, + CDNS_MCP_CONTROL_RST_DELAY, + CDNS_MCP_CONTROL_RST_DELAY); + + /* use hardware generated reset */ + cdns_updatel(cdns, CDNS_MCP_CONTROL, + CDNS_MCP_CONTROL_HW_RST, + CDNS_MCP_CONTROL_HW_RST); + + /* enable bus operations with clock and data */ + cdns_updatel(cdns, CDNS_MCP_CONFIG, + CDNS_MCP_CONFIG_OP, + CDNS_MCP_CONFIG_OP_NORMAL); + + /* commit changes */ + return cdns_update_config(cdns); +} +EXPORT_SYMBOL(sdw_cdns_exit_reset); + +/** + * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config + * @cdns: Cadence instance + */ +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns) { u32 mask; @@ -784,24 +831,8 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns) cdns_writel(cdns, CDNS_MCP_INTMASK, mask); - return 0; -} - -/** - * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config - * @cdns: Cadence instance - */ -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns) -{ - int ret; - - _cdns_enable_interrupt(cdns); - ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE, - CDNS_MCP_CONFIG_UPDATE_BIT); - if (ret < 0) - dev_err(cdns->dev, "Config update timedout\n"); - - return ret; + /* commit changes */ + return cdns_update_config(cdns); } EXPORT_SYMBOL(sdw_cdns_enable_interrupt); @@ -975,6 +1006,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns) cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL); cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL); + /* flush command FIFOs */ + cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST, + CDNS_MCP_CONTROL_CMD_RST); + /* Set cmd accept mode */ cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT, CDNS_MCP_CONTROL_CMD_ACCEPT); @@ -997,13 +1032,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns) /* Set cmd mode for Tx and Rx cmds */ val &= ~CDNS_MCP_CONFIG_CMD; - /* Set operation to normal */ - val &= ~CDNS_MCP_CONFIG_OP; - val |= CDNS_MCP_CONFIG_OP_NORMAL; - cdns_writel(cdns, CDNS_MCP_CONFIG, val); - return 0; + /* commit changes */ + return cdns_update_config(cdns); } EXPORT_SYMBOL(sdw_cdns_init); diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h index 0b72b70947352..1a67728c5000f 100644 --- a/drivers/soundwire/cadence_master.h +++ b/drivers/soundwire/cadence_master.h @@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id); int sdw_cdns_init(struct sdw_cdns *cdns); int sdw_cdns_pdi_init(struct sdw_cdns *cdns, struct sdw_cdns_stream_config config); +int sdw_cdns_exit_reset(struct sdw_cdns *cdns); int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns); #ifdef CONFIG_DEBUG_FS diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 243af8198d1c6..a2da04946f0b4 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1050,8 +1050,6 @@ static int intel_probe(struct platform_device *pdev) if (ret) goto err_init; - ret = sdw_cdns_enable_interrupt(&sdw->cdns); - /* Read the PDI config and initialize cadence PDI */ intel_pdi_init(sdw, &config); ret = sdw_cdns_pdi_init(&sdw->cdns, config); @@ -1069,6 +1067,18 @@ static int intel_probe(struct platform_device *pdev) goto err_init; } + ret = sdw_cdns_enable_interrupt(&sdw->cdns); + if (ret < 0) { + dev_err(sdw->cdns.dev, "cannot enable interrupts\n"); + goto err_init; + } + + ret = sdw_cdns_exit_reset(&sdw->cdns); + if (ret < 0) { + dev_err(sdw->cdns.dev, "unable to exit bus reset sequence\n"); + goto err_init; + } + /* Register DAIs */ ret = intel_register_dai(sdw); if (ret) { -- 2.25.1