Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp484386imu; Fri, 16 Nov 2018 05:41:40 -0800 (PST) X-Google-Smtp-Source: AJdET5cl+McWYeEPrpVyNuUGoHEa6Pws+mFlKmRKZOWmakwuCfq2CEKPa8fMpORcPn153iGifTsR X-Received: by 2002:a17:902:ac1:: with SMTP id 59-v6mr10867437plp.110.1542375700794; Fri, 16 Nov 2018 05:41:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542375700; cv=none; d=google.com; s=arc-20160816; b=cgerhl8/V9WRMccKowcX0z5rpVOI4Ud+9v97F/+wUGGrhi19zNUaoRDFg540L+0YC7 xbGJl7JeRf/BU+vfPIERQ9CMqzhg26xzuRtfkQEpgsSVQDbXT3Ss3/x31KyXSVtJiZyC l8xObu+He/Usa4HoGrA6qGlqfKPep0x2PswFMfZpfh640zTz2th4AuLpguAEButHmf4H FS58LcXOskK0UbsPHhfhEwgNGQwIMgTCdXaVgvFS/ZZhuRCiyu/wHXtAvLVPB/f5R1TX N23R341x62bDcHuL3TceLGQ6g64ueFpRpuCJ5GO5fzSd53UBDOE6Z9BD0d6K9ATFWXF4 xO7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=kpdHsnSaDksoYrwIWxUtPRPoIcpruLZ8WHjFcxMWpdY=; b=PXCuungn+3hwZ350GvJsRI84cJ7lUyJHioQvraLNmjwzt8H7Pf2IPr3HdFB+Fdku2o NS5qYS+52lfMsf5+rHnvMC3FpDMrPYXxRUtUKrLoO9dTlEqzMYIyvRk+jVie4O8Fsram mrvFjwlp7llOaC+v7lw+l7KYLOy6c2pgvI3i1pH4qRbSACKxecqfWUISPEP2YD8uvmNs p2dbdAZ5xY9V+Z1LDogzAUyQiVnjdUNyknbL/PYkrAniPDA3fpRsV4y836EVm0mlST3U UOXsOgsnFU7BEUptPdYPtUsHiMKBrwWw7v/DsZNaN3/b2owe9tlLCtOPth88Oet6KtDq jF5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=GIFl59UZ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v5si3233620pfe.52.2018.11.16.05.41.26; Fri, 16 Nov 2018 05:41:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=GIFl59UZ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389989AbeKPXxJ (ORCPT + 99 others); Fri, 16 Nov 2018 18:53:09 -0500 Received: from lelv0142.ext.ti.com ([198.47.23.249]:51092 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728079AbeKPXxJ (ORCPT ); Fri, 16 Nov 2018 18:53:09 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id wAGDebgo076274; Fri, 16 Nov 2018 07:40:37 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1542375637; bh=kpdHsnSaDksoYrwIWxUtPRPoIcpruLZ8WHjFcxMWpdY=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=GIFl59UZWltSdxfA/LqYqOrOzY9mFsoovv03sxNSd5+2lxeaPCo4pTap6P0REoFll Ni7yl5Qfd46rCFvEz7SUnfZjocSGM3g/vU2upcSbdLA5NzxuBHd1QAE3eEUS6fUelY 5tsWlrHNZLVX1qC9p1oGA2IrDwiTCjQ01VXUmaSo= Received: from DFLE108.ent.ti.com (dfle108.ent.ti.com [10.64.6.29]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id wAGDebGc116422 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 16 Nov 2018 07:40:37 -0600 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE108.ent.ti.com (10.64.6.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Fri, 16 Nov 2018 07:40:36 -0600 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Fri, 16 Nov 2018 07:40:36 -0600 Received: from feketebors.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id wAGDeQws005228; Fri, 16 Nov 2018 07:40:34 -0600 From: Peter Ujfalusi To: Mark Brown , Liam Girdwood CC: , , , , , Subject: [PATCH 2/4] ASoC: davinci-mcasp: Update PDIR (pin direction) register handling Date: Fri, 16 Nov 2018 15:41:39 +0200 Message-ID: <20181116134141.17396-3-peter.ujfalusi@ti.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181116134141.17396-1-peter.ujfalusi@ti.com> References: <20181116134141.17396-1-peter.ujfalusi@ti.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When McASP is master and the PDIR for the clock pins are configured as outputs before the clocking is configured it will output whatever clock is generated at the moment internally. The clock will switch to the correct rate only when the we start the clock generators. To avoid this we must only set the pin as output after the clock is configured and enabled. AXR pins configured as outputs behaves somehow interesting as well: when McASP is not enabled and the pin is selected as output it will not honor the DISMOD settings for the inactive state, but will pull the pin down. Add a new bitfield and mark the pins there which needs to be output and set the pins only at the time when they will behave correctly. On stream stop configure the pins back to input which makes them to obey the global pin configuration regarding to pull up/down. Signed-off-by: Peter Ujfalusi --- sound/soc/davinci/davinci-mcasp.c | 88 ++++++++++++++++++++++++++----- sound/soc/davinci/davinci-mcasp.h | 29 ++++------ 2 files changed, 85 insertions(+), 32 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 740030b4d37a..0f3911be1c8e 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -95,6 +96,8 @@ struct davinci_mcasp { int sysclk_freq; bool bclk_master; + unsigned long pdir; /* Pin direction bitfield */ + /* McASP FIFO related */ u8 txnumevt; u8 rxnumevt; @@ -169,6 +172,30 @@ static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp) return !(aclkxctl & TX_ASYNC) && rxfmctl & AFSRE; } +static inline void mcasp_set_clk_pdir(struct davinci_mcasp *mcasp, bool enable) +{ + u32 bit = PIN_BIT_AMUTE; + + for_each_set_bit_from(bit, &mcasp->pdir, PIN_BIT_AFSR + 1) { + if (enable) + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); + else + mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); + } +} + +static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable) +{ + u32 bit; + + for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AFSR) { + if (enable) + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); + else + mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); + } +} + static void mcasp_start_rx(struct davinci_mcasp *mcasp) { if (mcasp->rxnumevt) { /* enable FIFO */ @@ -220,6 +247,8 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp) /* Start clocks */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); + mcasp_set_clk_pdir(mcasp, true); + /* Activate serializer(s) */ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); @@ -230,6 +259,8 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp) (cnt < 100000)) cnt++; + mcasp_set_axr_pdir(mcasp, true); + /* Release TX state machine */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); /* Release Frame Sync generator */ @@ -260,8 +291,10 @@ static void mcasp_stop_rx(struct davinci_mcasp *mcasp) * In synchronous mode stop the TX clocks if no other stream is * running */ - if (mcasp_is_synchronous(mcasp) && !mcasp->streams) + if (mcasp_is_synchronous(mcasp) && !mcasp->streams) { + mcasp_set_clk_pdir(mcasp, false); mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0); + } mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0); mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); @@ -287,6 +320,9 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp) */ if (mcasp_is_synchronous(mcasp) && mcasp->streams) val = TXHCLKRST | TXCLKRST | TXFSRST; + else + mcasp_set_clk_pdir(mcasp, false); + mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); @@ -296,6 +332,8 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp) mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); } + + mcasp_set_axr_pdir(mcasp, false); } static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream) @@ -446,8 +484,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); - mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); + /* BCLK */ + set_bit(PIN_BIT_ACLKX, &mcasp->pdir); + set_bit(PIN_BIT_ACLKR, &mcasp->pdir); + /* Frame Sync */ + set_bit(PIN_BIT_AFSX, &mcasp->pdir); + set_bit(PIN_BIT_AFSR, &mcasp->pdir); + mcasp->bclk_master = 1; break; case SND_SOC_DAIFMT_CBS_CFM: @@ -458,8 +501,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); + /* BCLK */ + set_bit(PIN_BIT_ACLKX, &mcasp->pdir); + set_bit(PIN_BIT_ACLKR, &mcasp->pdir); + /* Frame Sync */ + clear_bit(PIN_BIT_AFSX, &mcasp->pdir); + clear_bit(PIN_BIT_AFSR, &mcasp->pdir); + mcasp->bclk_master = 1; break; case SND_SOC_DAIFMT_CBM_CFS: @@ -470,8 +518,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); - mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); + /* BCLK */ + clear_bit(PIN_BIT_ACLKX, &mcasp->pdir); + clear_bit(PIN_BIT_ACLKR, &mcasp->pdir); + /* Frame Sync */ + set_bit(PIN_BIT_AFSX, &mcasp->pdir); + set_bit(PIN_BIT_AFSR, &mcasp->pdir); + mcasp->bclk_master = 0; break; case SND_SOC_DAIFMT_CBM_CFM: @@ -482,8 +535,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, - ACLKX | AFSX | ACLKR | AHCLKR | AFSR); + /* BCLK */ + clear_bit(PIN_BIT_ACLKX, &mcasp->pdir); + clear_bit(PIN_BIT_ACLKR, &mcasp->pdir); + /* Frame Sync */ + clear_bit(PIN_BIT_AFSX, &mcasp->pdir); + clear_bit(PIN_BIT_AFSR, &mcasp->pdir); + mcasp->bclk_master = 0; break; default: @@ -598,11 +656,11 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, if (dir == SND_SOC_CLOCK_OUT) { mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); - mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); + set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); } else { mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); + clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); } mcasp->sysclk_freq = freq; @@ -775,17 +833,21 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, mcasp->serial_dir[i]); if (mcasp->serial_dir[i] == TX_MODE && tx_ser < max_active_serializers) { - mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), DISMOD_LOW, DISMOD_MASK); + set_bit(PIN_BIT_AXR(i), &mcasp->pdir); tx_ser++; } else if (mcasp->serial_dir[i] == RX_MODE && rx_ser < max_active_serializers) { - mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); + clear_bit(PIN_BIT_AXR(i), &mcasp->pdir); rx_ser++; } else if (mcasp->serial_dir[i] == INACTIVE_MODE) { mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), SRMOD_INACTIVE, SRMOD_MASK); + clear_bit(PIN_BIT_AXR(i), &mcasp->pdir); + } else if (mcasp->serial_dir[i] == TX_MODE) { + /* Unused TX pins, clear PDIR */ + clear_bit(PIN_BIT_AXR(i), &mcasp->pdir); } } diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index afddc8010c54..acb024ab6a9d 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h @@ -108,27 +108,18 @@ /* * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits - */ -#define AXR(n) (1<