From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39D9225B098 for ; Sun, 5 Jul 2026 03:38:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783222725; cv=none; b=XSqYQTGjSW/KkoWxx3y9b9cCH8MxmJr/0341KOmYqpaAVHNpWbkhyijNRzheth1Hn7x3+isyoOf5D3Gqtff+sM+QHWcspaPXxMW5WfKMeT+qQN1kcLK1uR+IbdCQWXWbSHA3Ia5i03CEjjqqBcGLaHRVse6kPSBFSykvewAbsA4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783222725; c=relaxed/simple; bh=gpP+0OPb65JufIYBtBuQ5iW58m7xh3zj/lE27gs4jcc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YUsAji0uFyx/DJDlsbVyrnuKAnqPgP9uBsb6ah6fvtht/jPxEeIY8XIOxlUYFOyc7Vv1II06ma849Sb6+TST8Re2LQRwzl/f6SALbTSLD9B6w2+gu5iUm9sIsN9qZrj/dpMEGBNhPdaXDzg8R2wnWgKl1AJdRuEkMV2toDR4it8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l6/GdeJu; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l6/GdeJu" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-2cc80b585bfso2519035ad.0 for ; Sat, 04 Jul 2026 20:38:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783222722; x=1783827522; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Aach3+WVLTqKJMNp90n9nPIIb7yYxYlE5c55bwYrGsA=; b=l6/GdeJuqIoW+M8bo9CY9zOCPjk+qiAxEzzGtiuSJKBbb5A4OqfLYJC6y6O7Z1BBxH VnTq85S9GSGw/XlIRmb2hKavD0DFaeGwjlDCYgbMNztWU/swylZpCv7BN6GWrHn5k+5F 8doj8eHjikjLR69j0PmUxg7VLXc68BufC77Ehvq/OdfMWisXVn/FxvpPg2snKXs+APV2 rYCB5Sbr0hLFeD/ecCg9Byrt90udTDFCRXvKWy+5xCsmNpRk9ciYNd914nl6r86M3ZPI S1+bu2GFsB7LS1c/MGlOCWjsSo+yx+6GK0Pn5CxvaTuINpPZeHG6A/K8a0eMWuo5CnbW RppA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783222722; x=1783827522; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Aach3+WVLTqKJMNp90n9nPIIb7yYxYlE5c55bwYrGsA=; b=lF9WSuXsv7e84X6WO7nYGIyX5k9ZxjVx9AphB0+RTj518MfLV6AmXfN+eBDZhh8xBf S2w92rUJymmLsj2tH8SyTid4zNj1X+e3iS7aNJpwtd0zezJ2Y5ZDc+ABGxD5fus/JjpF xjvkwhPZGQ5nshTWbvwtgoX5V+zl5vzvXcF+MDR1S2CLv4FKxauyDM2I85IFn4CFCJAq iJTTKz7iaAHpooWSSJ3xa8tz1EoBQddvWYW1ogmjmBWCUcbgzfbksGZbK8p6uaDaKKuJ BSYGf8sCrDGGnszBmr6ZVHqUZgflUuzZ6F4UanE937OWC0XBe4X40kKcAm9PQXWQjfRO cirw== X-Forwarded-Encrypted: i=1; AHgh+RoH8B2lDdVnAjS4WrcV09HDTLrx5Bcy2LN4ITIlbqTnQTxMB26gKp+jxv2tzFlmscM3HTb+rXvt1Lh38XY=@vger.kernel.org X-Gm-Message-State: AOJu0YwqshNJwL4uCuMCcMC+etzJ0jz8EIZh150rnXWX/cZW80YqUSiy hyp8xj9Y6VpWbFuaTQl3UwQ90wjNvZnHL50Z1XKrjRf7uQR/cQ/nbNaa X-Gm-Gg: AfdE7cnaE+Arn8+k58MQ2UOi09WWtEWJ0zB/mAPNUkc2H16WLufx40ZSL0iaZ3tlRPK BM8uPc7ewqaQILsPFctY9n77LHsXiBYnSSQMmwh0VMCgzIHdUKjTRWLioH5+E9+/4B0yNA3WpUa DpLgWqKIVzmQ3ExoSTkWjMEXz5SzKUnrTjyuDYkjG/TAIHulYefOwJ+s2IrlUs8iPMJ1LpUSobs 4m1J/PHfBy/cCE1qsNOlkMP9dRvUFFA8paLDG6Ss/bt068ywuoNxMKz/C81GMf1yVOJCdUyLlmt O5wr4ayzJKKW6E6iXIQ5+tKe8HEdh50J411fXgclgmTvR9mm0tG7cI760KgAJEnc9KgFwUSKT9E JE6Z/mF+yoeFxMXZGc3fQ56/K94gkoDlnhpFapHRIbsoqcWNwAc9zoA1l/AAfwwqnhyLB+Z53/k szozkq08piO0mmvcfJWpGZiSF5JnVyXgbblIxIdBkAIwo53E4Ae2t9Gqg3kGpa1hzzIYUz/LPqi SdcjUsBYyVTSxNBI3KO9MpW07dbXNJOrA5Ko6xqPSouAph/AHjCcze/3JfOpLkM X-Received: by 2002:a17:902:cf03:b0:2cc:85a7:36ee with SMTP id d9443c01a7336-2cc85a74f00mr10023415ad.32.1783222721624; Sat, 04 Jul 2026 20:38:41 -0700 (PDT) Received: from [192.168.2.3] ([2403:581e:d87e:0:fc2d:ed31:e80e:412d]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b41c364d5sm35463845c88.14.2026.07.04.20.38.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jul 2026 20:38:40 -0700 (PDT) From: James Calligeros Date: Sun, 05 Jul 2026 13:37:51 +1000 Subject: [PATCH v3 2/7] ASoC: apple: mca: Separate data & clock port setup Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20260705-apple-audio-redux-v3-2-ff7a7afe2b6b@gmail.com> References: <20260705-apple-audio-redux-v3-0-ff7a7afe2b6b@gmail.com> In-Reply-To: <20260705-apple-audio-redux-v3-0-ff7a7afe2b6b@gmail.com> To: =?utf-8?q?Martin_Povi=C5=A1er?= , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: asahi@lists.linux.dev, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, James Calligeros X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5618; i=jcalligeros99@gmail.com; h=from:subject:message-id; bh=FIXHrT0P9Yru6Rq6uRiDH66R8LjOM4VlY3Dltq8mEXE=; b=owGbwMvMwCV2xczoYuD3ygTG02pJDFmeF7e0f5oubyd0wlL/s3Dhwl6pvtANFU94irYl9rY5N seJ7NbsmMjCIMbFYCmmyLKhSchjthHbzX6Ryr0wc1iZQIZIizQwAAELA19uYl6pkY6Rnqm2oZ6h kY6xjhEDF6cATHWlAcN/F5ZTr9b+aHQ84+pnGanFodTA5f1+Bt9x/gnamuJmacWSjAwXhPnTxOX kjp4r/i7ie/fD1iVzVB9KvHZzq3zOtDFj53ZWAA== X-Developer-Key: i=jcalligeros99@gmail.com; a=openpgp; fpr=B08212489B3206D98F1479BDD43632D151F77960 From: Martin Povišer Up until now FEs were always the clock providers -- feeding the clocks on any ports (BEs) they are attached to. This will soon change and FEs will be allowed to be clock consumers. Once that happens, the routing of clocks and data will to some degree decouple. In advance of the change, make preparations: * Narrow down semantics of what was formerly the 'port_driver' field to refer to clocks only. * On 'startup' of BEs, separate the clock and data aspects of the port setup. Signed-off-by: Martin Povišer Signed-off-by: James Calligeros --- sound/soc/apple/mca.c | 63 ++++++++++++++++--------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c index ebe116f32661..feaf60a4912f 100644 --- a/sound/soc/apple/mca.c +++ b/sound/soc/apple/mca.c @@ -133,8 +133,8 @@ struct mca_cluster { struct clk *clk_parent; struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1]; - bool port_started[SNDRV_PCM_STREAM_LAST + 1]; - int port_driver; /* The cluster driving this cluster's port */ + bool port_clk_started[SNDRV_PCM_STREAM_LAST + 1]; + int port_clk_driver; /* The cluster driving this cluster's port */ bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1]; struct device_link *pd_link; @@ -157,7 +157,7 @@ struct mca_data { struct reset_control *rstc; struct device_link *pd_link; - /* Mutex for accessing port_driver of foreign clusters */ + /* Mutex for accessing port_clk_driver of foreign clusters */ struct mutex port_mutex; int nclusters; @@ -311,7 +311,7 @@ static bool mca_fe_clocks_in_use(struct mca_cluster *cl) for (i = 0; i < mca->nclusters; i++) { be_cl = &mca->clusters[i]; - if (be_cl->port_driver != cl->no) + if (be_cl->port_clk_driver != cl->no) continue; for_each_pcm_streams(stream) { @@ -331,10 +331,10 @@ static int mca_be_prepare(struct snd_pcm_substream *substream, struct mca_cluster *fe_cl; int ret; - if (cl->port_driver < 0) + if (cl->port_clk_driver < 0) return -EINVAL; - fe_cl = &mca->clusters[cl->port_driver]; + fe_cl = &mca->clusters[cl->port_clk_driver]; /* * Typically the CODECs we are paired with will require clocks @@ -708,12 +708,15 @@ static const struct snd_soc_dai_ops mca_fe_ops = { .trigger = mca_fe_trigger, }; -static bool mca_be_started(struct mca_cluster *cl) +/* + * Is there a FE attached which will be feeding this port's clocks? + */ +static bool mca_be_clk_started(struct mca_cluster *cl) { int stream; for_each_pcm_streams(stream) - if (cl->port_started[stream]) + if (cl->port_clk_started[stream]) return true; return false; } @@ -744,28 +747,38 @@ static int mca_be_startup(struct snd_pcm_substream *substream, fe_cl = mca_dai_to_cluster(snd_soc_rtd_to_cpu(fe, 0)); - if (mca_be_started(cl)) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no), + cl->base + REG_PORT_DATA_SEL); + mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA, + PORT_ENABLES_TX_DATA); + } + + if (mca_be_clk_started(cl)) { /* * Port is already started in the other direction. * Make sure there isn't a conflict with another cluster - * driving the port. + * driving the port clocks. */ - if (cl->port_driver != fe_cl->no) + if (cl->port_clk_driver != fe_cl->no) return -EINVAL; - cl->port_started[substream->stream] = true; + cl->port_clk_started[substream->stream] = true; return 0; } - writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA, - cl->base + REG_PORT_ENABLES); writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1), cl->base + REG_PORT_CLOCK_SEL); + writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no), cl->base + REG_PORT_DATA_SEL); + + mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_CLOCKS, + PORT_ENABLES_CLOCKS); + scoped_guard(mutex, &mca->port_mutex) - cl->port_driver = fe_cl->no; - cl->port_started[substream->stream] = true; + cl->port_clk_driver = fe_cl->no; + cl->port_clk_started[substream->stream] = true; return 0; } @@ -776,17 +789,21 @@ static void mca_be_shutdown(struct snd_pcm_substream *substream, struct mca_cluster *cl = mca_dai_to_cluster(dai); struct mca_data *mca = cl->host; - cl->port_started[substream->stream] = false; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA, 0); + writel_relaxed(0, cl->base + REG_PORT_DATA_SEL); + } - if (!mca_be_started(cl)) { + cl->port_clk_started[substream->stream] = false; + if (!mca_be_clk_started(cl)) { /* * Were we the last direction to shutdown? - * Turn off the lights. + * Turn off the lights (clocks). */ - writel_relaxed(0, cl->base + REG_PORT_ENABLES); - writel_relaxed(0, cl->base + REG_PORT_DATA_SEL); + mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_CLOCKS, 0); + writel_relaxed(0, cl->base + REG_PORT_CLOCK_SEL); scoped_guard(mutex, &mca->port_mutex) - cl->port_driver = -1; + cl->port_clk_driver = -1; } } @@ -1092,7 +1109,7 @@ static int apple_mca_probe(struct platform_device *pdev) cl->host = mca; cl->no = i; cl->base = base + CLUSTER_STRIDE * i; - cl->port_driver = -1; + cl->port_clk_driver = -1; cl->clk_parent = of_clk_get(pdev->dev.of_node, i); if (IS_ERR(cl->clk_parent)) { dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n", -- 2.55.0