From nobody Mon Jun 8 08:28:04 2026 Received: from outbound2.mail.transip.nl (outbound2.mail.transip.nl [149.210.149.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CDFB11799F; Sun, 31 May 2026 04:09:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=149.210.149.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780200551; cv=none; b=BRdX9XSWEr2YSKAt9oMiMgEvOG2uUj2UJ93QSkwoC0jdQc+pmS8sL+H1kTgzdAk6uf4ZwaLTiDEC3nylEjWx+nX01x1cSOBJ/lRryI2leGCOn21SHAzYzv7MroUqiOvsjukI+VE1+xj9uJRSurgmVTNwFkS+/HI1Ai7J/9CQ0CU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780200551; c=relaxed/simple; bh=EFHHCYXr3fMmz6eVGmuvtYq2zRZZc+3f/ppJsbk9fEk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h2sDgNvU7vZkRJV8D1Kx8+Zdn+fl/QxrB+iZWtVA5cGjyrxYFKVdKCX2QDd3RXjkQrfCihymapfm2H6Z32+GhJ/BtPNJKmfI63P+CC0Cdqk4Q6wnpbxaRE2z1/UBwkcj28zvV4vA0OQwIFyYeGEBoORgdu67uS7sAPBo9oFx4yc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=herrie.org; spf=pass smtp.mailfrom=herrie.org; dkim=pass (2048-bit key) header.d=herrie.org header.i=@herrie.org header.b=GUtI6Up6; arc=none smtp.client-ip=149.210.149.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=herrie.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=herrie.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=herrie.org header.i=@herrie.org header.b="GUtI6Up6" Received: from submission10.mail.transip.nl (unknown [10.103.8.161]) by outbound2.mail.transip.nl (Postfix) with ESMTP id 4gSk9r11pWzYf0J; Sun, 31 May 2026 06:09:04 +0200 (CEST) Received: from herrie-desktop.. (180-93-184-31.ftth.glasoperator.nl [31.184.93.180]) by submission10.mail.transip.nl (Postfix) with ESMTPA id 4gSk9q3xplz1g92mb; Sun, 31 May 2026 06:09:03 +0200 (CEST) From: Herman van Hazendonk To: Bjorn Andersson , Conor Dooley , devicetree@vger.kernel.org, Krzysztof Kozlowski , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Michael Turquette , Rob Herring , Stephen Boyd Subject: [PATCH v2 1/3] dt-bindings: clock: qcom,lcc: add MSM8x60 family compatibles Date: Sun, 31 May 2026 06:09:00 +0200 Message-ID: <44986bb00724bd127e95651a8cc54fd018430c96.1780197511.git.github.com@herrie.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: ClueGetter at submission10.mail.transip.nl DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=transip-a; d=herrie.org; t=1780200543; h=from:subject:to:references: in-reply-to:date:mime-version; bh=tpfIdewfd+xDczBgMN5skX/AIdc7U38DWllBaQyGfdo=; b=GUtI6Up6NfsaKPZ1nhpQ5PAjLUmapsVIAE8R4PvASLnMZjyRehM/epx3fYlFTHKX06Ua8u /Hv9xaaU4X+olU6DAQg6p3BXD4gH7zKDN62E7vbJtzEhW9arb59Fn52SWHGj2KSXQeeRgQ Vlu90BPPzUYrQ+mfwPUY1seDdtd4Cpx4EErDGPzPjhbJarqr+q6qBZEDhxePzlFmlpu56W RhqhiZHsKKu6k2idL3FzIFF4w6IW4pgSrsw2zjQBR9rtm+kKZMxhaFFWaENFt6X09/3k+Q tTDGZArMqH38uK8oHBKJvNJWZBymYJ2UTO96yfodzk9Hk7Q055TtlpRnUTplZw== X-Report-Abuse-To: abuse@transip.nl Content-Type: text/plain; charset="utf-8" Add "qcom,lcc-msm8260", "qcom,lcc-msm8660" and "qcom,lcc-apq8060" to the qcom,lcc enum and to the existing parent-clock-name conditional block that already covers apq8064/msm8960. The MSM8x60 family (MSM8260/MSM8660/APQ8060) is the Scorpion-class generation preceding MSM8960; its LPASS Clock Controller is fed by the same pxo board source and pll4_vote parents as apq8064/msm8960, and the codec-fed slave-mode I2S/PCM clocks have the same names, so the existing apq8064/msm8960 conditional block applies unchanged once the new compatibles are listed. This allows board DTs using the new compatibles to pass dt_binding_check; the actual driver support is added by a later patch in this series. Signed-off-by: Herman van Hazendonk --- Documentation/devicetree/bindings/clock/qcom,lcc.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,lcc.yaml b/Docume= ntation/devicetree/bindings/clock/qcom,lcc.yaml index 55985e562a34..bbdad157f03f 100644 --- a/Documentation/devicetree/bindings/clock/qcom,lcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,lcc.yaml @@ -12,9 +12,12 @@ maintainers: properties: compatible: enum: + - qcom,lcc-apq8060 - qcom,lcc-apq8064 - qcom,lcc-ipq8064 - qcom,lcc-mdm9615 + - qcom,lcc-msm8260 + - qcom,lcc-msm8660 - qcom,lcc-msm8960 =20 clocks: @@ -46,7 +49,10 @@ allOf: compatible: contains: enum: + - qcom,lcc-apq8060 - qcom,lcc-apq8064 + - qcom,lcc-msm8260 + - qcom,lcc-msm8660 - qcom,lcc-msm8960 then: properties: --=20 2.43.0 From nobody Mon Jun 8 08:28:04 2026 Received: from outbound9.mail.transip.nl (outbound9.mail.transip.nl [136.144.136.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2F7323EAA0; Sun, 31 May 2026 04:09:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=136.144.136.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780200550; cv=none; b=Wp0FxrFc1sIDaahp+Bw8L9HqK5GN1yViQ2m9sQxKtzsXNMTiSb4lICjNtUCdzkyoKaOuVjhQPX/F531rQB86jeCebjUDEtJ2Zmck5z1NzfL6082oXwXCqst1WlQKPsBpDXBHYJyKMmMTXJuKjjUdTEf7nUFTriM5vQxGRf8P4dM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780200550; c=relaxed/simple; bh=0pF0rhg2hHdPbQ2Luyn/7WqsTAcxwqew8Vs8I2dTWc4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YVp4D1UOO3ZO3TKWJkIiuLjjTcvH+rmEz81T3wYevJ0QwkyDRnhkE/Vdp3n9QbI6gAh2h1Nqp8E+niMtAgjHmFETggbSmPsNc1nNaVMoS/4yB88fIGFcnmqxTTordI11CySsSwleZNKUzkfHjO0sn95WDXxWBMtCjPXwMrfNijA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=herrie.org; spf=pass smtp.mailfrom=herrie.org; dkim=pass (2048-bit key) header.d=herrie.org header.i=@herrie.org header.b=lhURLWz7; arc=none smtp.client-ip=136.144.136.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=herrie.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=herrie.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=herrie.org header.i=@herrie.org header.b="lhURLWz7" Received: from submission10.mail.transip.nl (unknown [10.103.8.161]) by outbound9.mail.transip.nl (Postfix) with ESMTP id 4gSk9r5r6wzTPNc5; Sun, 31 May 2026 06:09:04 +0200 (CEST) Received: from herrie-desktop.. (180-93-184-31.ftth.glasoperator.nl [31.184.93.180]) by submission10.mail.transip.nl (Postfix) with ESMTPA id 4gSk9r1WYyz1g92mX; Sun, 31 May 2026 06:09:04 +0200 (CEST) From: Herman van Hazendonk To: Bjorn Andersson , Conor Dooley , devicetree@vger.kernel.org, Krzysztof Kozlowski , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Michael Turquette , Rob Herring , Stephen Boyd Subject: [PATCH v2 2/3] dt-bindings: clock: qcom: add lcc-msm8660 LPASS clock IDs Date: Sun, 31 May 2026 06:09:01 +0200 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: ClueGetter at submission10.mail.transip.nl DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=transip-a; d=herrie.org; t=1780200544; h=from:subject:to:references: in-reply-to:date:mime-version; bh=rW2SLXzGi1/eJwT7d4iDn2tWeHOxsLuq9eRAWU8zmV8=; b=lhURLWz7ZnRrHIp9Jwlh3Fardp4gWacXCQ/I+7kgXLEFqM/apkUSdsVom09GWPADEA7yf9 BfKWZuhi+w/5fkr49RsUONYlAV8eJxE0GskJtQOrvfIwXV64MfE8ZiJ8AI//1dnkZWfBRi Hs6w3QPAlyeQPf3DlVc/FQyGrn1Si0muv4PqoJjKrCeRWT60zsnQONwjNAary4P+7PWhTd ziqy8YoJfswsE9sUmSfmqLi+ZeMz6Y0WrciQSN1znriTCoKPQX/iD0Xt3aAaHntNlXRUkk nFdmtCPYj5aD8ilrnROcUnHpYMoFqXB4KCYJSYGUxPvlMcaZB9qKGsIznSSHLw== X-Report-Abuse-To: abuse@transip.nl Content-Type: text/plain; charset="utf-8" Add the dt-binding clock-ID header for the MSM8x60 family (MSM8260/MSM8660/APQ8060) Low Power Audio SubSystem Clock Controller (LCC). The header enumerates the LPASS clocks consumed by the qcom,apq8060-lpaif sound card and the codec/AIF nodes downstream of it. It mirrors the format and ID range of the existing LCC headers for newer Qualcomm SoCs (lcc-msm8960, lcc-msm8974) so the drivers/clk/qcom/lcc-msm8660.c driver can be hooked up the same way once it lands. Signed-off-by: Herman van Hazendonk --- include/dt-bindings/clock/qcom,lcc-msm8660.h | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,lcc-msm8660.h diff --git a/include/dt-bindings/clock/qcom,lcc-msm8660.h b/include/dt-bind= ings/clock/qcom,lcc-msm8660.h new file mode 100644 index 000000000000..d5d9b0d71a78 --- /dev/null +++ b/include/dt-bindings/clock/qcom,lcc-msm8660.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_LCC_MSM8660_H +#define _DT_BINDINGS_CLK_LCC_MSM8660_H + +/* + * MSM8x60 family (MSM8260/MSM8660/APQ8060) LPASS Clock Controller (LCC) + * clock IDs. These are compatible with MSM8960 LCC as MSM8x60 and + * MSM8960 share the same audio subsystem clock architecture. + */ + +#define PLL4 0 +#define MI2S_OSR_SRC 1 +#define MI2S_OSR_CLK 2 +#define MI2S_DIV_CLK 3 +#define MI2S_BIT_DIV_CLK 4 +#define MI2S_BIT_CLK 5 +#define PCM_SRC 6 +#define PCM_CLK_OUT 7 +#define PCM_CLK 8 +#define SLIMBUS_SRC 9 +#define AUDIO_SLIMBUS_CLK 10 +#define SPS_SLIMBUS_CLK 11 +#define CODEC_I2S_MIC_OSR_SRC 12 +#define CODEC_I2S_MIC_OSR_CLK 13 +#define CODEC_I2S_MIC_DIV_CLK 14 +#define CODEC_I2S_MIC_BIT_DIV_CLK 15 +#define CODEC_I2S_MIC_BIT_CLK 16 +#define SPARE_I2S_MIC_OSR_SRC 17 +#define SPARE_I2S_MIC_OSR_CLK 18 +#define SPARE_I2S_MIC_DIV_CLK 19 +#define SPARE_I2S_MIC_BIT_DIV_CLK 20 +#define SPARE_I2S_MIC_BIT_CLK 21 +#define CODEC_I2S_SPKR_OSR_SRC 22 +#define CODEC_I2S_SPKR_OSR_CLK 23 +#define CODEC_I2S_SPKR_DIV_CLK 24 +#define CODEC_I2S_SPKR_BIT_DIV_CLK 25 +#define CODEC_I2S_SPKR_BIT_CLK 26 +#define SPARE_I2S_SPKR_OSR_SRC 27 +#define SPARE_I2S_SPKR_OSR_CLK 28 +#define SPARE_I2S_SPKR_DIV_CLK 29 +#define SPARE_I2S_SPKR_BIT_DIV_CLK 30 +#define SPARE_I2S_SPKR_BIT_CLK 31 + +#endif --=20 2.43.0 From nobody Mon Jun 8 08:28:04 2026 Received: from outbound10.mail.transip.nl (outbound10.mail.transip.nl [136.144.136.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F64C263C8F; Sun, 31 May 2026 04:09:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=136.144.136.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780200553; cv=none; b=HgpOJNtZ5/TT8XpIdN+3fHDW5/I1M2qca9wU1rojJTcQ6o4jpLKcP3L++5UPUg9n8/XRWSrJs2D9cecTTLjD3sOjriQgZqqS45aeePsQrLNtS4EbThTR2pVOv+pfh7ha7XVpfiTnMTGEtVxSIFeDXfiQIiOh1+XRfHhZG3fD4zI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780200553; c=relaxed/simple; bh=RllGI30v7s/jc87HganImQLdwf4Q9DvHvOq+m4Tsi/c=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q8gBYvwKna2o1HBqq7wpqByodXUV1TULyOrNas3MVzS1vvh6Mwp7g4BhXHiipke/xy0F5eUAmyAfWVa9an6zEDEF7vhlUokLNQ9uZKIoJHBfDQWZttSjVn/VRENkgvKOwtUqDLxwazQgixJoT93jBx4QN8cRotvtS2N+t/wUtb8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=herrie.org; spf=pass smtp.mailfrom=herrie.org; dkim=pass (2048-bit key) header.d=herrie.org header.i=@herrie.org header.b=luIpqhIw; arc=none smtp.client-ip=136.144.136.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=herrie.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=herrie.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=herrie.org header.i=@herrie.org header.b="luIpqhIw" Received: from submission10.mail.transip.nl (unknown [10.103.8.161]) by outbound10.mail.transip.nl (Postfix) with ESMTP id 4gSk9s4QvdzTPNX6; Sun, 31 May 2026 06:09:05 +0200 (CEST) Received: from herrie-desktop.. (180-93-184-31.ftth.glasoperator.nl [31.184.93.180]) by submission10.mail.transip.nl (Postfix) with ESMTPA id 4gSk9r6bHjz1g92mW; Sun, 31 May 2026 06:09:04 +0200 (CEST) From: Herman van Hazendonk To: Bjorn Andersson , Conor Dooley , devicetree@vger.kernel.org, Krzysztof Kozlowski , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Michael Turquette , Rob Herring , Stephen Boyd Subject: [PATCH v2 3/3] clk: qcom: add MSM8x60 LCC (LPASS) driver Date: Sun, 31 May 2026 06:09:02 +0200 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: ClueGetter at submission10.mail.transip.nl DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=transip-a; d=herrie.org; t=1780200545; h=from:subject:to:references: in-reply-to:date:mime-version; bh=58851k7dxqxXk6rXsgJgSXYV21hona3ss3fC+VT/0bc=; b=luIpqhIwdNZuuHm984PAP2eBojUj3PDsfKoxA37lYviRQH/BcffZBNxi8XfvKOygVbDNk1 iPF4h7XlxEIzOVginQS8D1BCtRXROO24ssjqzidnjYtTC6TEwKYe0c3+C4JlAtawjnFmkv N9MKWcJ7kt3vxBZYBEp/6tlf1TmaxIwVA5tNrxXNDJDwwmDk4CgmCTjWJaGeOA1AeY9FWU XOTbO9ZHyFKC8my/RAC+MnaPYRy0VjZiFhtioSFA+QCslyrKQc5+sHzY/CqmqGpvvQTvxA TLFq75R18yal58rZlvcDDX6+TK4raAgNSleCNT4Rhg7fQYpZW1ZKegjdSitCbQ== X-Report-Abuse-To: abuse@transip.nl Content-Type: text/plain; charset="utf-8" Add a clock driver for the LPASS (Low Power Audio SubSystem) Clock Controller on the MSM8x60 family (MSM8260/MSM8660/APQ8060) - the Scorpion-class generation that preceded MSM8960's Krait CPUs. The register layout, parent muxing and divider topology of the LPASS PLL/clk fabric differ from MSM8960's LCC enough that a clean separate driver is simpler than parameterising mmcc-msm8960.c. Both drivers can coexist in tree (different KConfig options, different match table, different device-tree compatible). Used on the HP TouchPad (Tenderloin) where the LPASS Q6 audio DSP needs functional MI2S / SLIMBus / PCM clocks before audio playback or capture works. Signed-off-by: Herman van Hazendonk --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lcc-msm8660.c | 551 +++++++++++++++++++++++++++++++++ 3 files changed, 561 insertions(+) create mode 100644 drivers/clk/qcom/lcc-msm8660.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index d9cff5b0281d..2ea95f69355e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -547,6 +547,15 @@ config MSM_LCC_8960 Say Y if you want to use audio devices such as i2s, pcm, SLIMBus, etc. =20 +config MSM_LCC_8660 + tristate "MSM8x60 LPASS Clock Controller" + depends on ARM || COMPILE_TEST + help + Support for the LPASS clock controller on the MSM8x60 family + (MSM8260/MSM8660/APQ8060). MSM8960 is the newer + Krait-based generation handled separately by MSM_LCC_8960. + Say Y if you want to use audio devices such as i2s, pcm, SLIMBus. + config MDM_GCC_9607 tristate "MDM9607 Global Clock Controller" depends on ARM || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index e100cfd6a52d..41c973d7db59 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_MSM_GCC_8974) +=3D gcc-msm8974.o obj-$(CONFIG_MSM_GCC_8976) +=3D gcc-msm8976.o obj-$(CONFIG_MSM_GCC_8994) +=3D gcc-msm8994.o obj-$(CONFIG_MSM_GCC_8996) +=3D gcc-msm8996.o +obj-$(CONFIG_MSM_LCC_8660) +=3D lcc-msm8660.o obj-$(CONFIG_MSM_LCC_8960) +=3D lcc-msm8960.o obj-$(CONFIG_MSM_GCC_8998) +=3D gcc-msm8998.o obj-$(CONFIG_MSM_GPUCC_8998) +=3D gpucc-msm8998.o diff --git a/drivers/clk/qcom/lcc-msm8660.c b/drivers/clk/qcom/lcc-msm8660.c new file mode 100644 index 000000000000..f71846d493f8 --- /dev/null +++ b/drivers/clk/qcom/lcc-msm8660.c @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2026 Herman van Hazendonk + * + * Qualcomm MSM8x60 family (MSM8260/MSM8660/APQ8060) LPASS Clock Controlle= r driver. + * + * Split from lcc-msm8960.c because the MSM8x60 family is a separate + * SoC generation (Scorpion) from MSM8960 (Krait). The clock topology is + * compatible but PLL4 runs at a different rate (540.672 MHz, L=3D22) and = the + * driver has no need for the MDM9615 CXO patch or the 492 MHz frequency p= lan. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" + +static struct clk_pll pll4 =3D { + .l_reg =3D 0x4, + .m_reg =3D 0x8, + .n_reg =3D 0xc, + .config_reg =3D 0x14, + .mode_reg =3D 0x0, + .status_reg =3D 0x18, + .status_bit =3D 16, + .clkr.hw.init =3D &(struct clk_init_data){ + .name =3D "pll4", + .parent_data =3D &(const struct clk_parent_data){ + .fw_name =3D "pxo", .name =3D "pxo_board", + }, + .num_parents =3D 1, + .ops =3D &clk_pll_ops, + }, +}; + +enum { + P_PXO, + P_PLL4, +}; + +static const struct parent_map lcc_pxo_pll4_map[] =3D { + { P_PXO, 0 }, + { P_PLL4, 2 } +}; + +static const struct clk_parent_data lcc_pxo_pll4[] =3D { + { .fw_name =3D "pxo", .name =3D "pxo_board" }, + { .fw_name =3D "pll4_vote", .name =3D "pll4_vote" }, +}; + +/* + * MSM8x60 PLL4 runs at 540.672 MHz (24.576 MHz * 22, L=3D0x16). + * Divisors taken from the legacy webOS clock-8x60.c driver. + * AIF_OSR has an 8-bit M/N counter, so 512000 Hz is not achievable with + * this PLL frequency and is intentionally omitted from the 540 MHz tables. + */ +static const struct freq_tbl clk_tbl_aif_osr_540[] =3D { + { 768000, P_PLL4, 4, 1, 176 }, + { 1024000, P_PLL4, 4, 1, 132 }, + { 1536000, P_PLL4, 4, 1, 88 }, + { 2048000, P_PLL4, 4, 1, 66 }, + { 3072000, P_PLL4, 4, 1, 44 }, + { 4096000, P_PLL4, 4, 1, 33 }, + { 6144000, P_PLL4, 4, 1, 22 }, + { 8192000, P_PLL4, 2, 1, 33 }, + { 12288000, P_PLL4, 4, 1, 11 }, + { 24576000, P_PLL4, 2, 1, 11 }, + { 27000000, P_PXO, 1, 0, 0 }, + { } +}; + +static const struct freq_tbl clk_tbl_aif_osr_393[] =3D { + { 512000, P_PLL4, 4, 1, 192 }, + { 768000, P_PLL4, 4, 1, 128 }, + { 1024000, P_PLL4, 4, 1, 96 }, + { 1536000, P_PLL4, 4, 1, 64 }, + { 2048000, P_PLL4, 4, 1, 48 }, + { 3072000, P_PLL4, 4, 1, 32 }, + { 4096000, P_PLL4, 4, 1, 24 }, + { 6144000, P_PLL4, 4, 1, 16 }, + { 8192000, P_PLL4, 4, 1, 12 }, + { 12288000, P_PLL4, 4, 1, 8 }, + { 24576000, P_PLL4, 4, 1, 4 }, + { 27000000, P_PXO, 1, 0, 0 }, + { } +}; + +#define CLK_AIF_OSR_SRC(prefix, _ns, _md) \ +static struct clk_rcg prefix##_osr_src =3D { \ + .ns_reg =3D _ns, \ + .md_reg =3D _md, \ + .mn =3D { \ + .mnctr_en_bit =3D 8, \ + .mnctr_reset_bit =3D 7, \ + .mnctr_mode_shift =3D 5, \ + .n_val_shift =3D 24, \ + .m_val_shift =3D 8, \ + .width =3D 8, \ + }, \ + .p =3D { \ + .pre_div_shift =3D 3, \ + .pre_div_width =3D 2, \ + }, \ + .s =3D { \ + .src_sel_shift =3D 0, \ + .parent_map =3D lcc_pxo_pll4_map, \ + }, \ + .freq_tbl =3D clk_tbl_aif_osr_393, \ + .clkr =3D { \ + .enable_reg =3D _ns, \ + .enable_mask =3D BIT(9), \ + .hw.init =3D &(struct clk_init_data){ \ + .name =3D #prefix "_osr_src", \ + .parent_data =3D lcc_pxo_pll4, \ + .num_parents =3D ARRAY_SIZE(lcc_pxo_pll4), \ + .ops =3D &clk_rcg_ops, \ + .flags =3D CLK_SET_RATE_GATE, \ + }, \ + }, \ +}; \ + +#define CLK_AIF_OSR_CLK(prefix, _ns, hr, en_bit) \ +static struct clk_branch prefix##_osr_clk =3D { \ + .halt_reg =3D hr, \ + .halt_bit =3D 1, \ + .halt_check =3D BRANCH_HALT_ENABLE, \ + .clkr =3D { \ + .enable_reg =3D _ns, \ + .enable_mask =3D BIT(en_bit), \ + .hw.init =3D &(struct clk_init_data){ \ + .name =3D #prefix "_osr_clk", \ + .parent_hws =3D (const struct clk_hw*[]){ \ + &prefix##_osr_src.clkr.hw, \ + }, \ + .num_parents =3D 1, \ + .ops =3D &clk_branch_ops, \ + .flags =3D CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; \ + +#define CLK_AIF_OSR_DIV_CLK(prefix, _ns, _width) \ +static struct clk_regmap_div prefix##_div_clk =3D { \ + .reg =3D _ns, \ + .shift =3D 10, \ + .width =3D _width, \ + .clkr =3D { \ + .hw.init =3D &(struct clk_init_data){ \ + .name =3D #prefix "_div_clk", \ + .parent_hws =3D (const struct clk_hw*[]){ \ + &prefix##_osr_src.clkr.hw, \ + }, \ + .num_parents =3D 1, \ + .ops =3D &clk_regmap_div_ops, \ + }, \ + }, \ +}; \ + +#define CLK_AIF_OSR_BIT_DIV_CLK(prefix, _ns, hr, en_bit) \ +static struct clk_branch prefix##_bit_div_clk =3D { \ + .halt_reg =3D hr, \ + .halt_bit =3D 0, \ + .halt_check =3D BRANCH_HALT_ENABLE, \ + .clkr =3D { \ + .enable_reg =3D _ns, \ + .enable_mask =3D BIT(en_bit), \ + .hw.init =3D &(struct clk_init_data){ \ + .name =3D #prefix "_bit_div_clk", \ + .parent_hws =3D (const struct clk_hw*[]){ \ + &prefix##_div_clk.clkr.hw, \ + }, \ + .num_parents =3D 1, \ + .ops =3D &clk_branch_ops, \ + .flags =3D CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; \ + +#define CLK_AIF_OSR_BIT_CLK(prefix, _ns, _shift) \ +static struct clk_regmap_mux prefix##_bit_clk =3D { \ + .reg =3D _ns, \ + .shift =3D _shift, \ + .width =3D 1, \ + .clkr =3D { \ + .hw.init =3D &(struct clk_init_data){ \ + .name =3D #prefix "_bit_clk", \ + .parent_data =3D (const struct clk_parent_data[]){ \ + { .hw =3D &prefix##_bit_div_clk.clkr.hw, }, \ + { .fw_name =3D #prefix "_codec_clk", \ + .name =3D #prefix "_codec_clk", }, \ + }, \ + .num_parents =3D 2, \ + .ops =3D &clk_regmap_mux_closest_ops, \ + .flags =3D CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; + +CLK_AIF_OSR_SRC(mi2s, 0x48, 0x4c) +CLK_AIF_OSR_CLK(mi2s, 0x48, 0x50, 17) +CLK_AIF_OSR_DIV_CLK(mi2s, 0x48, 4) +CLK_AIF_OSR_BIT_DIV_CLK(mi2s, 0x48, 0x50, 15) +CLK_AIF_OSR_BIT_CLK(mi2s, 0x48, 14) + +/* + * CLK_AIF_OSR_DIV - Audio Interface with divider clocks. + * + * MSM8x60 LPASS AIF register layout, verified against the legacy + * downstream Samsung MSM8660 source and the webOS clock-8x60.c + * CLK_AIF_BIT macro. Both legacy sources agree on the bit assignment: + * the bit-divider field starts at offset 10 and is four bits wide; + * bit 14 doubles as the cdiv external-source select; BIT_DIV branch + * enable is BIT(15); OSR branch enable is BIT(17); the BIT clock mux + * select is BIT(18) for codec_i2s and spare_i2s (mi2s uses bit 14, + * handled explicitly above this macro); reset is BIT(19). + * + * Earlier revisions of this driver used a width of 8 here, inherited + * from lcc-msm8960.c whose enables are at BIT(19) and BIT(21) and so + * do not overlap a wide divider field. On MSM8x60 the enables are at + * BIT(15) and BIT(17), so a width of 8 made the divider field cover + * bits 10 through 17 and a read-modify-write on the divider would + * clobber the two branch gates. A width of 4 confines the divider to + * bits 10 through 13, matching the standalone mi2s div clock above + * and what the legacy stack programs. + */ +#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr) \ + CLK_AIF_OSR_SRC(prefix, _ns, _md) \ + CLK_AIF_OSR_CLK(prefix, _ns, hr, 17) \ + CLK_AIF_OSR_DIV_CLK(prefix, _ns, 4) \ + CLK_AIF_OSR_BIT_DIV_CLK(prefix, _ns, hr, 15) \ + CLK_AIF_OSR_BIT_CLK(prefix, _ns, 18) + +CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68); +CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80); +CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74); +CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c); + +/* PCM frequency table for MSM8x60 with PLL4 at 540.672 MHz */ +static const struct freq_tbl clk_tbl_pcm_540[] =3D { + { 256000, P_PLL4, 4, 1, 528 }, + { 512000, P_PLL4, 4, 1, 264 }, + { 768000, P_PLL4, 4, 1, 176 }, + { 1024000, P_PLL4, 4, 1, 132 }, + { 1536000, P_PLL4, 4, 1, 88 }, + { 2048000, P_PLL4, 4, 1, 66 }, + { 3072000, P_PLL4, 4, 1, 44 }, + { 4096000, P_PLL4, 4, 1, 33 }, + { 6144000, P_PLL4, 4, 1, 22 }, + { 8192000, P_PLL4, 2, 1, 33 }, + { 12288000, P_PLL4, 4, 1, 11 }, + { 24576000, P_PLL4, 2, 1, 11 }, + { 27000000, P_PXO, 1, 0, 0 }, + { } +}; + +static const struct freq_tbl clk_tbl_pcm_393[] =3D { + { 256000, P_PLL4, 4, 1, 384 }, + { 512000, P_PLL4, 4, 1, 192 }, + { 768000, P_PLL4, 4, 1, 128 }, + { 1024000, P_PLL4, 4, 1, 96 }, + { 1536000, P_PLL4, 4, 1, 64 }, + { 2048000, P_PLL4, 4, 1, 48 }, + { 3072000, P_PLL4, 4, 1, 32 }, + { 4096000, P_PLL4, 4, 1, 24 }, + { 6144000, P_PLL4, 4, 1, 16 }, + { 8192000, P_PLL4, 4, 1, 12 }, + { 12288000, P_PLL4, 4, 1, 8 }, + { 24576000, P_PLL4, 4, 1, 4 }, + { 27000000, P_PXO, 1, 0, 0 }, + { } +}; + +static struct clk_rcg pcm_src =3D { + .ns_reg =3D 0x54, + .md_reg =3D 0x58, + .mn =3D { + .mnctr_en_bit =3D 8, + .mnctr_reset_bit =3D 7, + .mnctr_mode_shift =3D 5, + .n_val_shift =3D 16, + .m_val_shift =3D 16, + .width =3D 16, + }, + .p =3D { + .pre_div_shift =3D 3, + .pre_div_width =3D 2, + }, + .s =3D { + .src_sel_shift =3D 0, + .parent_map =3D lcc_pxo_pll4_map, + }, + .freq_tbl =3D clk_tbl_pcm_393, + .clkr =3D { + .enable_reg =3D 0x54, + .enable_mask =3D BIT(9), + .hw.init =3D &(struct clk_init_data){ + .name =3D "pcm_src", + .parent_data =3D lcc_pxo_pll4, + .num_parents =3D ARRAY_SIZE(lcc_pxo_pll4), + .ops =3D &clk_rcg_ops, + .flags =3D CLK_SET_RATE_GATE, + }, + }, +}; + +static struct clk_branch pcm_clk_out =3D { + .halt_reg =3D 0x5c, + .halt_bit =3D 0, + .halt_check =3D BRANCH_HALT_ENABLE, + .clkr =3D { + .enable_reg =3D 0x54, + .enable_mask =3D BIT(11), + .hw.init =3D &(struct clk_init_data){ + .name =3D "pcm_clk_out", + .parent_hws =3D (const struct clk_hw*[]){ + &pcm_src.clkr.hw + }, + .num_parents =3D 1, + .ops =3D &clk_branch_ops, + .flags =3D CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_mux pcm_clk =3D { + .reg =3D 0x54, + .shift =3D 10, + .width =3D 1, + .clkr =3D { + .hw.init =3D &(struct clk_init_data){ + .name =3D "pcm_clk", + .parent_data =3D (const struct clk_parent_data[]){ + { .hw =3D &pcm_clk_out.clkr.hw }, + { .fw_name =3D "pcm_codec_clk", .name =3D "pcm_codec_clk" }, + }, + .num_parents =3D 2, + .ops =3D &clk_regmap_mux_closest_ops, + .flags =3D CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg slimbus_src =3D { + .ns_reg =3D 0xcc, + .md_reg =3D 0xd0, + .mn =3D { + .mnctr_en_bit =3D 8, + .mnctr_reset_bit =3D 7, + .mnctr_mode_shift =3D 5, + .n_val_shift =3D 24, + .m_val_shift =3D 8, + .width =3D 8, + }, + .p =3D { + .pre_div_shift =3D 3, + .pre_div_width =3D 2, + }, + .s =3D { + .src_sel_shift =3D 0, + .parent_map =3D lcc_pxo_pll4_map, + }, + .freq_tbl =3D clk_tbl_aif_osr_393, + .clkr =3D { + .enable_reg =3D 0xcc, + .enable_mask =3D BIT(9), + .hw.init =3D &(struct clk_init_data){ + .name =3D "slimbus_src", + .parent_data =3D lcc_pxo_pll4, + .num_parents =3D ARRAY_SIZE(lcc_pxo_pll4), + .ops =3D &clk_rcg_ops, + .flags =3D CLK_SET_RATE_GATE, + }, + }, +}; + +static struct clk_branch audio_slimbus_clk =3D { + .halt_reg =3D 0xd4, + .halt_bit =3D 0, + .halt_check =3D BRANCH_HALT_ENABLE, + .clkr =3D { + .enable_reg =3D 0xcc, + .enable_mask =3D BIT(10), + .hw.init =3D &(struct clk_init_data){ + .name =3D "audio_slimbus_clk", + .parent_hws =3D (const struct clk_hw*[]){ + &slimbus_src.clkr.hw, + }, + .num_parents =3D 1, + .ops =3D &clk_branch_ops, + .flags =3D CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch sps_slimbus_clk =3D { + .halt_reg =3D 0xd4, + .halt_bit =3D 1, + .halt_check =3D BRANCH_HALT_ENABLE, + .clkr =3D { + .enable_reg =3D 0xcc, + .enable_mask =3D BIT(12), + .hw.init =3D &(struct clk_init_data){ + .name =3D "sps_slimbus_clk", + .parent_hws =3D (const struct clk_hw*[]){ + &slimbus_src.clkr.hw, + }, + .num_parents =3D 1, + .ops =3D &clk_branch_ops, + .flags =3D CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap *lcc_msm8660_clks[] =3D { + [PLL4] =3D &pll4.clkr, + [MI2S_OSR_SRC] =3D &mi2s_osr_src.clkr, + [MI2S_OSR_CLK] =3D &mi2s_osr_clk.clkr, + [MI2S_DIV_CLK] =3D &mi2s_div_clk.clkr, + [MI2S_BIT_DIV_CLK] =3D &mi2s_bit_div_clk.clkr, + [MI2S_BIT_CLK] =3D &mi2s_bit_clk.clkr, + [PCM_SRC] =3D &pcm_src.clkr, + [PCM_CLK_OUT] =3D &pcm_clk_out.clkr, + [PCM_CLK] =3D &pcm_clk.clkr, + [SLIMBUS_SRC] =3D &slimbus_src.clkr, + [AUDIO_SLIMBUS_CLK] =3D &audio_slimbus_clk.clkr, + [SPS_SLIMBUS_CLK] =3D &sps_slimbus_clk.clkr, + [CODEC_I2S_MIC_OSR_SRC] =3D &codec_i2s_mic_osr_src.clkr, + [CODEC_I2S_MIC_OSR_CLK] =3D &codec_i2s_mic_osr_clk.clkr, + [CODEC_I2S_MIC_DIV_CLK] =3D &codec_i2s_mic_div_clk.clkr, + [CODEC_I2S_MIC_BIT_DIV_CLK] =3D &codec_i2s_mic_bit_div_clk.clkr, + [CODEC_I2S_MIC_BIT_CLK] =3D &codec_i2s_mic_bit_clk.clkr, + [SPARE_I2S_MIC_OSR_SRC] =3D &spare_i2s_mic_osr_src.clkr, + [SPARE_I2S_MIC_OSR_CLK] =3D &spare_i2s_mic_osr_clk.clkr, + [SPARE_I2S_MIC_DIV_CLK] =3D &spare_i2s_mic_div_clk.clkr, + [SPARE_I2S_MIC_BIT_DIV_CLK] =3D &spare_i2s_mic_bit_div_clk.clkr, + [SPARE_I2S_MIC_BIT_CLK] =3D &spare_i2s_mic_bit_clk.clkr, + [CODEC_I2S_SPKR_OSR_SRC] =3D &codec_i2s_spkr_osr_src.clkr, + [CODEC_I2S_SPKR_OSR_CLK] =3D &codec_i2s_spkr_osr_clk.clkr, + [CODEC_I2S_SPKR_DIV_CLK] =3D &codec_i2s_spkr_div_clk.clkr, + [CODEC_I2S_SPKR_BIT_DIV_CLK] =3D &codec_i2s_spkr_bit_div_clk.clkr, + [CODEC_I2S_SPKR_BIT_CLK] =3D &codec_i2s_spkr_bit_clk.clkr, + [SPARE_I2S_SPKR_OSR_SRC] =3D &spare_i2s_spkr_osr_src.clkr, + [SPARE_I2S_SPKR_OSR_CLK] =3D &spare_i2s_spkr_osr_clk.clkr, + [SPARE_I2S_SPKR_DIV_CLK] =3D &spare_i2s_spkr_div_clk.clkr, + [SPARE_I2S_SPKR_BIT_DIV_CLK] =3D &spare_i2s_spkr_bit_div_clk.clkr, + [SPARE_I2S_SPKR_BIT_CLK] =3D &spare_i2s_spkr_bit_clk.clkr, +}; + +static const struct regmap_config lcc_msm8660_regmap_config =3D { + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .max_register =3D 0xfc, + .fast_io =3D true, +}; + +static const struct qcom_cc_desc lcc_msm8660_desc =3D { + .config =3D &lcc_msm8660_regmap_config, + .clks =3D lcc_msm8660_clks, + .num_clks =3D ARRAY_SIZE(lcc_msm8660_clks), +}; + +static const struct of_device_id lcc_msm8660_match_table[] =3D { + { .compatible =3D "qcom,lcc-msm8260" }, + { .compatible =3D "qcom,lcc-msm8660" }, + { .compatible =3D "qcom,lcc-apq8060" }, + { } +}; +MODULE_DEVICE_TABLE(of, lcc_msm8660_match_table); + +static int lcc_msm8660_probe(struct platform_device *pdev) +{ + const struct freq_tbl *aif_osr_tbl, *pcm_tbl; + struct regmap *regmap; + const char *plan_name; + u32 val; + int ret; + + regmap =3D qcom_cc_map(pdev, &lcc_msm8660_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * MSM8x60 should always boot with PLL4 L=3D22 (540.672 MHz). + * Detect anyway so a board with a non-standard L value still gets a + * coherent frequency plan instead of silently producing wrong rates. + */ + ret =3D regmap_read(regmap, 0x4, &val); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to read PLL4 L register\n"); + + if (val =3D=3D 0x16) { + aif_osr_tbl =3D clk_tbl_aif_osr_540; + pcm_tbl =3D clk_tbl_pcm_540; + plan_name =3D "540MHz"; + } else { + aif_osr_tbl =3D clk_tbl_aif_osr_393; + pcm_tbl =3D clk_tbl_pcm_393; + plan_name =3D "fallback 393MHz"; + } + + /* + * Pick the matching frequency table on both branches; assigning + * unconditionally also restores the default if this driver is + * ever rebound on a system whose PLL4 has been reprogrammed. + */ + slimbus_src.freq_tbl =3D aif_osr_tbl; + mi2s_osr_src.freq_tbl =3D aif_osr_tbl; + codec_i2s_mic_osr_src.freq_tbl =3D aif_osr_tbl; + spare_i2s_mic_osr_src.freq_tbl =3D aif_osr_tbl; + codec_i2s_spkr_osr_src.freq_tbl =3D aif_osr_tbl; + spare_i2s_spkr_osr_src.freq_tbl =3D aif_osr_tbl; + pcm_src.freq_tbl =3D pcm_tbl; + + dev_info(&pdev->dev, "PLL4 L=3D0x%x, using %s frequency plan\n", + val, plan_name); + + /* Enable PLL4 source on the LPASS Primary PLL Mux */ + regmap_write(regmap, 0xc4, 0x1); + + return qcom_cc_really_probe(&pdev->dev, &lcc_msm8660_desc, regmap); +} + +static struct platform_driver lcc_msm8660_driver =3D { + .probe =3D lcc_msm8660_probe, + .driver =3D { + .name =3D "lcc-msm8660", + .of_match_table =3D lcc_msm8660_match_table, + }, +}; +module_platform_driver(lcc_msm8660_driver); + +MODULE_DESCRIPTION("Qualcomm MSM8x60 LPASS Clock Controller driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:lcc-msm8660"); --=20 2.43.0