From nobody Fri Sep 25 00:01:22 2026 Received: from mail-wr2-f43.google.com (mail-wr2-f43.google.com [74.125.225.107]) (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 DCF9B43498C for ; Fri, 18 Sep 2026 09:55:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789725337; cv=none; b=dlexfAnDZi5tAabfbkrd4UlUhe2F2PT95V5TOwjLgNROyPiTDC47NgJ955O3ygU/wh77mMVu8RaYRCJqHZz+RtF9A1c2C1Flb/8fs8ZlNFMEpVfucs7gl0B4TPwew/e3MZOY+EzKwbcTqSUlddKG5Wk4f4MI9bzP0b8EhCP+imU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789725337; c=relaxed/simple; bh=Go39NKKMwkuXXP/SejpjyZo/TgbX2bfpHuiP0B8nCjc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Og9gEhNVeANFHqeeeZKWLAtMTgSzjyWtpqhOUHH5gEAF9tc51FIXufqKfDChlyaoE/gY4ZyGzv/vYyrBhMXFijJLSS+yVbOD69LLHqEJV4u4L7gxjSup50BdnCVGreGBPJ2dx3X3Pu/vob1Ef/TYJbJ2AMk2Oevpb4u8bIO+iJs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=TCyTeD3r; arc=none smtp.client-ip=74.125.225.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="TCyTeD3r" Received: by mail-wr2-f43.google.com with SMTP id ffacd0b85a97d-482f62ccdb1so168922f8f.1 for ; Fri, 18 Sep 2026 02:55:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1789725327; x=1790330127; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=piB6olxsDjTKBBKWtT/80MoIuyo/txOuxpczb55KJIY=; b=TCyTeD3r1rWRXVHPBT/wWxFFGTMJFKpAxfL0orZq2hMkItYdl/MXae5y8jiNemT0uU /BXziqBLyypXngR1Cs316bM8pt00O4wvCFnQY8FcPFf02zycmwgLTK8EeDmmA6u+URGZ mX2utb0El90eZ/Pr3G6JYY5byU7JvtbAvEHCOuS5R4Tk9PUCfDddeQNMLWmaC/LApDfM 6lvVidftX57Fcr2JkgkJgRVlEBA/x5d1cLwMVsJUuI70IVD0/VZK/C91G+56ZGLUG3cM v9x31ZSpdsexIuJrkp9tTbTZnCQsJmwPM7eHpBRZmPIp750WnA6kvwWKi37woWAG9DY2 xzPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789725327; x=1790330127; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=piB6olxsDjTKBBKWtT/80MoIuyo/txOuxpczb55KJIY=; b=fTYMyHd2ObGtxOC2nChqAljCZ1NMTDzuUli/COp5HtAOHFUnaafqL0UA1+pGlUx/Lf HIBFlnrSyMGCXvoPOV4OGJdx50O3rqnHoSym/UEJ5uCvIpqXkmGPipExr4udvSO8mPE9 eXBl6/uaX6Rxi5AZathz3TKNAC1L0HXnTfHCmB2l/4h93jZG8DCx6QWR+6ZyNfnMtHR1 TdJ4chNr462kna5PQ/deQNvoBDCpsATBxei6IWx1i1gZRGMW5t2uFEjkteD364rl+OkP Z3Gpzj9cNmhb4Mc4H+OnW8X075LUekTTGjF0v5EVHcyDT0dDATmQY3hveEdLSbYi0Jnx FWdw== X-Forwarded-Encrypted: i=1; AKwUvBzwO+Xn8PrLiV51uLkaWLBgPS61lJ5xS5BJ8+z5PsXNc/kg09BRZsmbpzSRGidZaw444sfi8NW3dw+xREg=@vger.kernel.org X-Gm-Message-State: AFuF++mFw2duR81zKkawc8vDpw5npM1B9rqL1Avrv0VZt6slL7THL+2h g9FVjAVxaedyIej8b4EHdnN8O4n3LKrDG6FnKHVJG+h8c3wm832h/mFjq3EIM7xmga4= X-Gm-Gg: AYBFou1s5jmb3WmUiR852nuRViWjTkaxX/nnkO+rap6OvkNukucpBBVMOOChyfnJ2pW W1fzFUm8do0LJvktdgGOY7rORQuDypoPnbCm6bxJaC0l7KT+A3THFoADnBHwBbHQDUwjl+9N2Cl J4jqqJCzhs6YQdCRd9VlwFOipbjZDruPe41IZOrGxQynZIw985yT8hgyUBvMlciH7ildZTcAf33 Fj6YMlNi3nKbI+ev/fKJ4n9UZEQ2kP6h8rHTwlVIOwkGvr4CVl4fQqv1yCrqy2u6S4GS/5/F/3C TKj8PuG3zjseQXw9zRmCqqUvQo/y2716NxHYFuned35zr/RlyA9MGr65FM9+bTbp7xZY7jry4gg lNSgR/Nm1nNyV4TXewi7nzgPx9COm9mRAqvG1B87mYibhAeaK3m4mp9sBgo5PWaBMKBatPU3W7f gU1405uh/BdQJF+iYiI9tSozBk/6Jo3Qw+6tFt6o7smkbgpzjTVbpCdoV3ZZMKQAqNg3zAfA== X-Received: by 2002:a05:6000:614:b0:487:fa3:764f with SMTP id ffacd0b85a97d-4871db0c610mr3127079f8f.20.1789725327020; Fri, 18 Sep 2026 02:55:27 -0700 (PDT) Received: from localhost ([195.94.147.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4871ff3a928sm3077276f8f.13.2026.09.18.02.55.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Sep 2026 02:55:26 -0700 (PDT) From: Andrea della Porta To: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , linux-pwm@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Florian Fainelli , Broadcom internal kernel review list , Andrea della Porta , devicetree@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Naushir Patuck , Stanimir Varbanov , mbrugger@suse.com, Sean Young , Julian Braha , "Gary Guo" , Christophe JAILLET Cc: Krzysztof Kozlowski Subject: [PATCH v9 1/3] dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller Date: Fri, 18 Sep 2026 11:59:00 +0200 Message-ID: X-Mailer: git-send-email 2.51.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 Content-Type: text/plain; charset="utf-8" From: Naushir Patuck Add the devicetree binding documentation for the PWM controller found in the Raspberry Pi RP1 chipset. Signed-off-by: Naushir Patuck Co-developed-by: Stanimir Varbanov Signed-off-by: Stanimir Varbanov Signed-off-by: Andrea della Porta Reviewed-by: Krzysztof Kozlowski --- .../bindings/pwm/raspberrypi,rp1-pwm.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/raspberrypi,rp1-p= wm.yaml diff --git a/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml= b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml new file mode 100644 index 0000000000000..be020583fd0ba --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/raspberrypi,rp1-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Raspberry Pi RP1 PWM controller + +maintainers: + - Naushir Patuck + - Andrea della Porta + - Stanimir Varbanov + +allOf: + - $ref: pwm.yaml# + +description: | + The PWM peripheral is a flexible waveform generator with a + variety of operational modes. It has the following features: + - four independent output channels + - 32-bit counter widths + - Seven output generation modes + - Optional per-channel output inversion + - Optional duty-cycle data FIFO with DMA support + - Optional sigma-delta noise shaping engine + Serves as a fan speed provider to other nodes for a PWM-connected + fan. + +properties: + compatible: + const: raspberrypi,rp1-pwm + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + "#pwm-cells": + const: 3 + + dmas: + maxItems: 1 + description: | + Phandle to the DMA controller and the channel specifier for + the duty-cycle FIFO. + + dma-names: + items: + - const: tx + +required: + - compatible + - reg + - clocks + +unevaluatedProperties: false + +examples: + - | + pwm@98000 { + compatible =3D "raspberrypi,rp1-pwm"; + reg =3D <0x98000 0x100>; + clocks =3D <&rp1_clocks 17>; + #pwm-cells =3D <3>; + }; --=20 2.35.3 From nobody Fri Sep 25 00:01:22 2026 Received: from mail-wr2-f12.google.com (mail-wr2-f12.google.com [74.125.225.76]) (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 3C41F431A44 for ; Fri, 18 Sep 2026 09:55:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789725337; cv=none; b=NfERf+B+XCcsWAYSDeLorv0kzrS24FN4mqc9TtxYeKU3+Ku8+Mu0mjNzLHqxwqgzpqtweCnONTd8Kfb8udNtf8UHo1kQ01k0W6IAW+xbwlK8vyE7Jno5h8MwUY9Y4OXgfqVqUiv7iFF7T919uDmnCHP9JxYmyX9U84xO6vaKuYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789725337; c=relaxed/simple; bh=5jDJZCK1dAkLaBomrgFIACF0fWSVbg1Gy7rY7vjlipc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=t+Ck+/MGX265tQVUL3HZ1jP4dUU6kwxKOomQud3X1cN5FENRxEr5DPatXXPK2VgcmSzr2rKSAl4VHfTbxRk3zbnfAloaUEW7VfPU1ejIZtxC9DRJ3Q0EAOUFWCrDgK27Bc20PWjP58FOv+5uMxxDvYmXd75J7k4xbYgRoPr2O4Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=FXU/jueq; arc=none smtp.client-ip=74.125.225.76 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="FXU/jueq" Received: by mail-wr2-f12.google.com with SMTP id ffacd0b85a97d-482f633ecdeso477434f8f.2 for ; Fri, 18 Sep 2026 02:55:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1789725328; x=1790330128; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GIgXOSySdXISVhB8ZvaUBblOfld5+4W7uDWlRac17ik=; b=FXU/jueqWy6szmv3gp0Iry5e0dJSLpuQVsHnXuX16LIz8ry0AxXdzCE1tisawkpbLR OstayF/PpQiS1XKDpJ5NowJBcGQiO1HRChsV3WFKbx5XggvbHe8rjVGtdLe4M3J36/64 hiiFxIdH0tpMXG97Y3SRMGawlsfP7/9GjPuo0GM/9qwAifZUi2gEO9aLtATHmiaVeuzQ uyX+7PsD7AHvMfHu4dF3bnQ/cin0/7/KDm/uNXsDTZ4QpDc4pxjgykCybYJ+drYGC9hd 6FX27pf1J5pNG40HFq2QSmi7gJ1MRCzr8o3mo/LtGDov91JrHEutEZ4pyi4PwGQ5doIw h4Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789725328; x=1790330128; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=GIgXOSySdXISVhB8ZvaUBblOfld5+4W7uDWlRac17ik=; b=1e4FSJSMLdv/cqOTykpxtNlbEelKTsL/pbmZzDi62w0dfKaAHMAvIc2qXT9Izr7iJK mY2QMBFEkiCK4Nny/szytI1uqvwC0Eu0tbZyfGnfCmemgCtWCny0Lg4yioUuG6qWiJqP Qyi9hkJalu6s4dK+CYnqWIDmUPuYgX5IjQfNU80+3zEbDhioi3M5eT6z2lKnppjMkl0A a91xk0cnY7GRmV33TESrcP0AtnE0yTwBVgTtyfnuDJvU+9PfnM3JPg5rO6DnLlq5Q0+n LvzkLsdRJvyAF1j32vHLen4k7Z44Tk8s8bgTsCtXI795jT3pPwTCLofrqLF0QUmf0aVP 4h0A== X-Forwarded-Encrypted: i=1; AKwUvBzzOGwbNJIB+wjfX8mXtjAo38gD5SoLp2pYU4fOAowtVeWwN3hv2u2Nn388H90PrOgo5qe+31yaVwxoPos=@vger.kernel.org X-Gm-Message-State: AFuF++mnX8YZEHHHCPokrej6cI93MDqmeHNo4TiVgDwDexl0RzvQDMtk /jPyoDjlJHV4o/6Op6cSclULHSwD8E0+lMpf/7MvbaT10HhnMIqP0eEnDAQaq6huhUk= X-Gm-Gg: AYBFou0YOsMJWsZWtanBnzHLCNSPoE46gbkQPbkSCiTZYgbQhsBMv98I/POh1tOkLU2 qo8zmiplmYzbd8z4DXNQKUMFOk4fhwBbMrEug5D6jY0Ngk57SahyNYHqjjGSmWltknq3hF3g15s Fy2xrHMkXqsRtv+RDJQTCMIBVyNE1szfgtn+NmFdya8muNpxgl8ye8lBxJnIrLwiUr83Jua+CzJ BhVCqRHKItZbS8QxDjH2ukiIo+57X4VjMLVMEjakjDTxrL8B4nrZqs949k6vtN75ATI5lWnXsvs rDssw8aV+4PbjROW2R7RDHvu1ts7unU5exRDlhHsyWYdGjjPrFDZpicQ1rEccSeoaD1y56b4Gjo OHCrIGDzq1hH5SMZXaxSgAonj51o9AtyDiX3n2ib+LoT53bsEof7+QMBQjLoMc1ORIE6BeueGjx s2/Bnq4hnyayt8syNpKCvgZPV09sGDLaFAS1b7OTY+A0C3kuU97PAK4QC34u2yER0oj1ZZ0fbk6 flu5LML X-Received: by 2002:a5d:5d09:0:b0:487:10df:89ea with SMTP id ffacd0b85a97d-4871e265f7bmr2387135f8f.30.1789725328041; Fri, 18 Sep 2026 02:55:28 -0700 (PDT) Received: from localhost ([195.94.147.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48720072efcsm2835112f8f.25.2026.09.18.02.55.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Sep 2026 02:55:27 -0700 (PDT) From: Andrea della Porta To: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , linux-pwm@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Florian Fainelli , Broadcom internal kernel review list , Andrea della Porta , devicetree@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Naushir Patuck , Stanimir Varbanov , mbrugger@suse.com, Sean Young , Julian Braha , "Gary Guo" , Christophe JAILLET Subject: [PATCH v9 2/3] pwm: rp1: Add RP1 PWM controller driver Date: Fri, 18 Sep 2026 11:59:01 +0200 Message-ID: <22f454003902173a7230d0aee5fbd7261fcc163e.1789724999.git.andrea.porta@suse.com> X-Mailer: git-send-email 2.51.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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Naushir Patuck The Raspberry Pi RP1 southbridge features an embedded PWM controller with 4 output channels, alongside an RPM interface to read the fan speed on the Raspberry Pi 5. Add the supporting driver. Signed-off-by: Naushir Patuck Co-developed-by: Stanimir Varbanov Signed-off-by: Stanimir Varbanov Signed-off-by: Andrea della Porta --- drivers/pwm/Kconfig | 8 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-rp1.c | 499 ++++++++++++++++++++++ include/soc/bcm2835/raspberrypi-pwm-rp1.h | 10 + 4 files changed, 518 insertions(+) create mode 100644 drivers/pwm/pwm-rp1.c create mode 100644 include/soc/bcm2835/raspberrypi-pwm-rp1.h diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 7297760868790..e1baec8d294d1 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -637,6 +637,14 @@ config PWM_ROCKCHIP Generic PWM framework driver for the PWM controller found on Rockchip SoCs. =20 +config PWM_RASPBERRYPI_RP1 + tristate "RP1 PWM support" + depends on MISC_RP1 || COMPILE_TEST + depends on HAS_IOMEM + select REGMAP_MMIO + help + PWM framework driver for Raspberry Pi RP1 controller. + config PWM_SAMSUNG tristate "Samsung PWM support" depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 5630a521a7cff..c07fd24f69f39 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT) +=3D pwm-rzg2l-gpt.o obj-$(CONFIG_PWM_RENESAS_RZ_MTU3) +=3D pwm-rz-mtu3.o obj-$(CONFIG_PWM_RENESAS_TPU) +=3D pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) +=3D pwm-rockchip.o +obj-$(CONFIG_PWM_RASPBERRYPI_RP1) +=3D pwm-rp1.o obj-$(CONFIG_PWM_SAMSUNG) +=3D pwm-samsung.o obj-$(CONFIG_PWM_SIFIVE) +=3D pwm-sifive.o obj-$(CONFIG_PWM_SL28CPLD) +=3D pwm-sl28cpld.o diff --git a/drivers/pwm/pwm-rp1.c b/drivers/pwm/pwm-rp1.c new file mode 100644 index 0000000000000..cfd38e46cc589 --- /dev/null +++ b/drivers/pwm/pwm-rp1.c @@ -0,0 +1,499 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * pwm-rp1.c + * + * Raspberry Pi RP1 PWM. + * + * Copyright =C2=A9 2026 Raspberry Pi Ltd. + * + * Author: Naushir Patuck (naush@raspberrypi.com) + * + * Based on the pwm-bcm2835 driver by: + * Bart Tanghe + * + * Datasheet: https://pip-assets.raspberrypi.com/categories/892-raspberry-= pi-5/documents/RP-008370-DS-1-rp1-peripherals.pdf?disposition=3Dinline + * + * Limitations: + * - Channels can be enabled/disabled through a global update flag, while = the + * period and duty per-channel registers are independently updatable, and + * they are latched on the end of (specific channel) period strobe. + * This means that period and duty changes might result in glitches if t= he + * period/duty is changed exactly during an end of period strobe. + * - Since the duty/period registers are freely updatable (do not depend on + * the global update flag), setting one of them close to the period end = and + * the other right afterwards results in a mixed output for that cycle b= ecause + * the write ops are not atomic. + * - The global update flag prevents mis-sampling of multi-bit bus signals= in + * the PWM clock domain. This ensures that all PWM channel settings upda= te + * on the same PWM clock cycle. Channels start in sync only if they shar= e the + * same period. + * - If both duty and period are set to 0, the output is a constant low si= gnal + * if polarity is normal or a constant high signal if polarity is invers= ed. + * - When disabled the output is driven to 0 if polarity is normal, or to 1 + * if polarity is inversed. + * - Disabling the PWM stops the output immediately, without waiting for c= urrent + * period to complete first. + * - Channels are phase-capable, but on RPi5, the firmware can use a chann= el + * phase register to report the RPM of the fan connected to that PWM + * channel. As a result, phase control will be ignored for now. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RP1_PWM_GLB_CTRL 0x000 +#define RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(chan) BIT(chan) +#define RP1_PWM_GLB_CTRL_SET_UPDATE BIT(31) + +#define RP1_PWM_CHAN_CTRL(chan) (0x014 + ((chan) * 0x10)) +#define RP1_PWM_CHAN_CTRL_POLARITY BIT(3) +#define RP1_PWM_CHAN_CTRL_FIFO_POP_MASK BIT(8) +#define RP1_PWM_CHAN_CTRL_MODE GENMASK(2, 0) +enum rp1_pwm_ctrl_mode { + RP1_PWM_CHAN_CTRL_MODE_ZERO, + RP1_PWM_CHAN_CTRL_MODE_TE_MS, + RP1_PWM_CHAN_CTRL_MODE_PC_MS, + RP1_PWM_CHAN_CTRL_MODE_PD_ENC, + RP1_PWM_CHAN_CTRL_MODE_MSB_SER, + RP1_PWM_CHAN_CTRL_MODE_PPM, + RP1_PWM_CHAN_CTRL_MODE_LE_MS, + RP1_PWM_CHAN_CTRL_MODE_LSB_SER, +}; + +#define RP1_PWM_CHAN_CTRL_DEFAULT (RP1_PWM_CHAN_CTRL_FIFO_POP_MASK + \ + FIELD_PREP(RP1_PWM_CHAN_CTRL_MODE, \ + RP1_PWM_CHAN_CTRL_MODE_TE_MS)) + +#define RP1_PWM_RANGE(chan) (0x018 + ((chan) * 0x10)) +#define RP1_PWM_PHASE(chan) (0x01C + ((chan) * 0x10)) +#define RP1_PWM_DUTY(chan) (0x020 + ((chan) * 0x10)) + +#define RP1_PWM_NUM_PWMS 4 + +struct rp1_pwm { + struct regmap *regmap; + struct clk *clk; + unsigned long clk_rate; + bool clk_enabled; + struct mutex lock; /* sync pm ops with read_tachometer */ +}; + +struct rp1_pwm_waveform { + u32 period_ticks; + u32 duty_ticks; + bool enabled; + bool inverted_polarity; +}; + +static const struct regmap_config rp1_pwm_regmap_config =3D { + .reg_bits =3D 32, + .val_bits =3D 32, + .reg_stride =3D 4, + .max_register =3D 0x60, +}; + +static int rp1_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *= pwm) +{ + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + u32 value; + int ret; + + /* update the changed registers on the next strobe to avoid glitches */ + ret =3D regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value); + if (ret) + return ret; + value |=3D RP1_PWM_GLB_CTRL_SET_UPDATE; + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, value); + + return 0; +} + +static int rp1_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + + /* init channel to reset defaults, preserving the polarity bit */ + regmap_update_bits(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), + ~(u32)RP1_PWM_CHAN_CTRL_POLARITY, RP1_PWM_CHAN_CTRL_DEFAULT); + return 0; +} + +static int rp1_pwm_round_waveform_tohw(struct pwm_chip *chip, + struct pwm_device *pwm, + const struct pwm_waveform *wf, + void *_wfhw) +{ + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + u64 period_ticks, duty_ticks, offset_ticks; + struct rp1_pwm_waveform *wfhw =3D _wfhw; + u64 clk_rate =3D rp1->clk_rate; + int ret =3D 0; + + if (!wf->period_length_ns) { + *wfhw =3D (typeof(*wfhw)){ + .enabled =3D false, + .inverted_polarity =3D false, + }; + return 0; + } + + period_ticks =3D mul_u64_u64_div_u64(wf->period_length_ns, clk_rate, NSEC= _PER_SEC); + + /* + * The period is limited to U32_MAX, and it will be decremented by one la= ter + * to allow 100% duty cycle. + */ + if (period_ticks > U32_MAX) { + period_ticks =3D U32_MAX; + } else if (period_ticks < 2) { + period_ticks =3D 2; + ret =3D 1; + } + + duty_ticks =3D mul_u64_u64_div_u64(wf->duty_length_ns, clk_rate, NSEC_PER= _SEC); + duty_ticks =3D min(duty_ticks, period_ticks); + offset_ticks =3D mul_u64_u64_div_u64(wf->duty_offset_ns, clk_rate, NSEC_P= ER_SEC); + if (offset_ticks >=3D period_ticks) + offset_ticks =3D period_ticks - 1; + if (duty_ticks && offset_ticks && + duty_ticks + offset_ticks >=3D period_ticks) { + wfhw->duty_ticks =3D period_ticks - duty_ticks; + wfhw->inverted_polarity =3D true; + } else { + wfhw->duty_ticks =3D duty_ticks; + wfhw->inverted_polarity =3D false; + } + /* Account for the extra tick at the end of the period */ + wfhw->period_ticks =3D period_ticks - 1; + + wfhw->enabled =3D true; + + return ret; +} + +static int rp1_pwm_round_waveform_fromhw(struct pwm_chip *chip, + struct pwm_device *pwm, + const void *_wfhw, + struct pwm_waveform *wf) +{ + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + const struct rp1_pwm_waveform *wfhw =3D _wfhw; + u64 clk_rate =3D rp1->clk_rate; + u64 ticks; + + *wf =3D (struct pwm_waveform){ }; + + if (!wfhw->enabled) + return 0; + + wf->period_length_ns =3D DIV_ROUND_UP_ULL(((u64)wfhw->period_ticks + 1) *= NSEC_PER_SEC, + (u32)clk_rate); + + if (!wfhw->inverted_polarity) { + wf->duty_length_ns =3D DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER= _SEC, + (u32)clk_rate); + } else { + if (wfhw->duty_ticks > (u64)wfhw->period_ticks + 1) { + /* 100% duty cycle case */ + ticks =3D 0; + } else { + ticks =3D (u64)wfhw->period_ticks + 1 - wfhw->duty_ticks; + } + wf->duty_length_ns =3D DIV_ROUND_UP_ULL(ticks * NSEC_PER_SEC, (u32)clk_r= ate); + wf->duty_offset_ns =3D DIV_ROUND_UP_ULL((u64)(wfhw->period_ticks + 1 - t= icks) * + NSEC_PER_SEC, (u32)clk_rate); + } + + return 0; +} + +static int rp1_pwm_write_waveform(struct pwm_chip *chip, + struct pwm_device *pwm, + const void *_wfhw) +{ + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + const struct rp1_pwm_waveform *wfhw =3D _wfhw; + u32 value, ctrl; + int ret; + + /* set polarity */ + ret =3D regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value); + if (ret) + return ret; + if (!wfhw->inverted_polarity) + value &=3D ~RP1_PWM_CHAN_CTRL_POLARITY; + else + value |=3D RP1_PWM_CHAN_CTRL_POLARITY; + regmap_write(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), value); + + /* early exit if disabled */ + ret =3D regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &ctrl); + if (ret) + return ret; + if (!wfhw->enabled) { + ctrl &=3D ~RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm); + /* just disable the channel and bail out early */ + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, ctrl); + return rp1_pwm_apply_config(chip, pwm); + } + + /* set period and duty cycle */ + regmap_write(rp1->regmap, + RP1_PWM_RANGE(pwm->hwpwm), wfhw->period_ticks); + regmap_write(rp1->regmap, + RP1_PWM_DUTY(pwm->hwpwm), wfhw->duty_ticks); + + /* enable the channel */ + ctrl |=3D RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm); + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, ctrl); + + return rp1_pwm_apply_config(chip, pwm); +} + +static int rp1_pwm_read_waveform(struct pwm_chip *chip, + struct pwm_device *pwm, + void *_wfhw) +{ + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + struct rp1_pwm_waveform *wfhw =3D _wfhw; + u32 value; + int ret; + + *wfhw =3D (typeof(*wfhw)) { + .period_ticks =3D 0, + .duty_ticks =3D 0, + }; + + ret =3D regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value); + if (ret) + return ret; + wfhw->enabled =3D !!(value & RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm)); + + ret =3D regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value); + if (ret) + return ret; + wfhw->inverted_polarity =3D !!(value & RP1_PWM_CHAN_CTRL_POLARITY); + + if (wfhw->enabled) { + ret =3D regmap_read(rp1->regmap, RP1_PWM_RANGE(pwm->hwpwm), &wfhw->perio= d_ticks); + if (ret) + return ret; + ret =3D regmap_read(rp1->regmap, RP1_PWM_DUTY(pwm->hwpwm), &wfhw->duty_t= icks); + if (ret) + return ret; + } + + return 0; +} + +static const struct pwm_ops rp1_pwm_ops =3D { + .sizeof_wfhw =3D sizeof(struct rp1_pwm_waveform), + .request =3D rp1_pwm_request, + .round_waveform_tohw =3D rp1_pwm_round_waveform_tohw, + .round_waveform_fromhw =3D rp1_pwm_round_waveform_fromhw, + .read_waveform =3D rp1_pwm_read_waveform, + .write_waveform =3D rp1_pwm_write_waveform, +}; + +int rp1_pwm_read_tachometer(struct device *dev) +{ + struct pwm_chip *chip; + struct rp1_pwm *rp1; + u32 tach_val; + int ret; + + if (!dev) + return -EINVAL; + + device_lock(dev); + + chip =3D dev_get_drvdata(dev); + if (!chip) { + ret =3D -ENODEV; + goto err_dev_unlock; + } + + rp1 =3D pwmchip_get_drvdata(chip); + if (!rp1) { + ret =3D -ENODEV; + goto err_dev_unlock; + } + + mutex_lock(&rp1->lock); + if (!rp1->clk_enabled) { + ret =3D -EBUSY; + goto err_clk_unlock; + } + + ret =3D regmap_read(rp1->regmap, RP1_PWM_PHASE(2), &tach_val); + if (ret) + goto err_clk_unlock; + + ret =3D (int)tach_val; + +err_clk_unlock: + mutex_unlock(&rp1->lock); +err_dev_unlock: + device_unlock(dev); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(rp1_pwm_read_tachometer, "RP1_PWM_FAN"); + +static int rp1_pwm_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + unsigned long clk_rate; + struct pwm_chip *chip; + void __iomem *base; + struct rp1_pwm *rp1; + int ret; + + chip =3D devm_pwmchip_alloc(dev, RP1_PWM_NUM_PWMS, sizeof(*rp1)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + rp1 =3D pwmchip_get_drvdata(chip); + ret =3D devm_mutex_init(dev, &rp1->lock); + if (ret) + return ret; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + rp1->regmap =3D devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config); + if (IS_ERR(rp1->regmap)) + return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regma= p\n"); + + rp1->clk =3D devm_clk_get(dev, NULL); + if (IS_ERR(rp1->clk)) + return dev_err_probe(dev, PTR_ERR(rp1->clk), "Clock not found\n"); + + ret =3D clk_prepare_enable(rp1->clk); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable clock\n"); + rp1->clk_enabled =3D true; + + ret =3D devm_clk_rate_exclusive_get(dev, rp1->clk); + if (ret) { + dev_err_probe(dev, ret, "Failed to get exclusive rate\n"); + goto err_disable_clk; + } + + clk_rate =3D clk_get_rate(rp1->clk); + if (!clk_rate) { + ret =3D dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n"); + goto err_disable_clk; + } + /* + * To prevent u64 overflow in period calculations: + * mul_u64_u64_div_u64(period_ns, clk_rate, NSEC_PER_SEC) + * If clk_rate > 1 GHz, the result can overflow. + */ + if (clk_rate > HZ_PER_GHZ) { + ret =3D dev_err_probe(dev, -EINVAL, "Clock rate > 1 GHz is not supported= \n"); + goto err_disable_clk; + } + rp1->clk_rate =3D clk_rate; + + chip->ops =3D &rp1_pwm_ops; + chip->atomic =3D true; + + platform_set_drvdata(pdev, chip); + + ret =3D pwmchip_add(chip); + if (ret) { + dev_err_probe(dev, ret, "Failed to register PWM chip\n"); + goto err_disable_clk; + } + + return 0; + +err_disable_clk: + clk_disable_unprepare(rp1->clk); + + return ret; +} + +static void rp1_pwm_remove(struct platform_device *pdev) +{ + struct pwm_chip *chip =3D platform_get_drvdata(pdev); + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + + pwmchip_remove(chip); + + if (rp1->clk_enabled) { + clk_disable_unprepare(rp1->clk); + rp1->clk_enabled =3D false; + } +} + +static int rp1_pwm_suspend(struct device *dev) +{ + struct pwm_chip *chip =3D dev_get_drvdata(dev); + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + + mutex_lock(&rp1->lock); + if (rp1->clk_enabled) { + clk_disable_unprepare(rp1->clk); + rp1->clk_enabled =3D false; + } + mutex_unlock(&rp1->lock); + + return 0; +} + +static int rp1_pwm_resume(struct device *dev) +{ + struct pwm_chip *chip =3D dev_get_drvdata(dev); + struct rp1_pwm *rp1 =3D pwmchip_get_drvdata(chip); + int ret; + + mutex_lock(&rp1->lock); + ret =3D clk_prepare_enable(rp1->clk); + if (ret) { + dev_err(dev, "Failed to enable clock on resume: %pe\n", ERR_PTR(ret)); + goto err_unlock; + } + rp1->clk_enabled =3D true; + +err_unlock: + mutex_unlock(&rp1->lock); + + return ret; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(rp1_pwm_pm_ops, rp1_pwm_suspend, rp1_pwm_r= esume); + +static const struct of_device_id rp1_pwm_of_match[] =3D { + { .compatible =3D "raspberrypi,rp1-pwm" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rp1_pwm_of_match); + +static struct platform_driver rp1_pwm_driver =3D { + .probe =3D rp1_pwm_probe, + .remove =3D rp1_pwm_remove, + .driver =3D { + .name =3D "rp1-pwm", + .of_match_table =3D rp1_pwm_of_match, + .pm =3D pm_ptr(&rp1_pwm_pm_ops), + }, +}; +module_platform_driver(rp1_pwm_driver); + +MODULE_DESCRIPTION("RP1 PWM driver"); +MODULE_AUTHOR("Naushir Patuck "); +MODULE_AUTHOR("Andrea della Porta "); +MODULE_LICENSE("GPL"); diff --git a/include/soc/bcm2835/raspberrypi-pwm-rp1.h b/include/soc/bcm283= 5/raspberrypi-pwm-rp1.h new file mode 100644 index 0000000000000..3be0892da667e --- /dev/null +++ b/include/soc/bcm2835/raspberrypi-pwm-rp1.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __SOC_RASPBERRY_PWM_RP1_H__ +#define __SOC_RASPBERRY_PWM_RP1_H__ + +#include + +int rp1_pwm_read_tachometer(struct device *dev); + +#endif /* __SOC_RASPBERRY_PWM_RP1_H__ */ --=20 2.35.3 From nobody Fri Sep 25 00:01:22 2026 Received: from mail-wr2-f26.google.com (mail-wr2-f26.google.com [74.125.225.90]) (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 5F0FF43802B for ; Fri, 18 Sep 2026 09:55:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.90 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789725337; cv=none; b=Ek17KKDAMvxeKr6oknsiesYSZvRCrjPi6BFCFkg5AgHsGamDnotlbNmPMLrCks2Ae1gfSIdXR6YzbBe4CJ6BHmxXxBrQm7p/DqwwSrFT89w43bdX+R6FrTH2qOeOOxHzr8rFvSxivqPZ5x03VeJqdNsaDLh0hubJZk2fmuAHLbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789725337; c=relaxed/simple; bh=NyT3bvkYhBzVis/qc4NVpDUc0HxiHbXcgKHaKLAMasY=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hssdl3wcD2vI+Lau/yV2z4/XpGgw4CAfy7gxvK4vSqKHrigH5aYKK2dL5xh+9R/A7nW7L6KxVaFxpxBw2s9JsdAbEaibTwIOxq2hk3slXcqKDVlOPMI3+2LhZN1jFXqqJmh/pYlyL2iOnhgOK9MiFmybI2SboGS+WKRh4bhFTX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=ICB15+dM; arc=none smtp.client-ip=74.125.225.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="ICB15+dM" Received: by mail-wr2-f26.google.com with SMTP id ffacd0b85a97d-4843f22dc83so356654f8f.1 for ; Fri, 18 Sep 2026 02:55:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1789725329; x=1790330129; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=RUWg5GWqhMeDrgGwJjMhc1B+7LHRy8TQo04xcORPTAE=; b=ICB15+dMW8qgOThkSxsnuoekJONG4TpcpLrrqabzQyhY67+KGirTMj/xyuTKbsvmzw 2nTT666mqYUWivLtnqIBiKk1mjVqs8hKYmvokDAC30ww7stroOIETdV5mekvKP6e2Enk J6HGGwP1z5xuJXqPlEOutMW4z6hSSY+5vNsufn4lfPHDZsRm7nWtW4WYA/q5t8XpxxFX 9dQUo1tqOzEsoXlEfM65y7QECASTu+h9gafAHHlhjxGspKDu9rl+FxxBstwwWL30L1X8 iJ4gjx+ejLTGp0qZjLL+IUOb43z92KTTCjXPAnAB+Arqo0rvJ6Y8xu5Vst9RtMO7cnDI fgEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789725329; x=1790330129; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=RUWg5GWqhMeDrgGwJjMhc1B+7LHRy8TQo04xcORPTAE=; b=10ZI6FYR+18/CgUyoHKkIog4qZaiAZRjzqHvlWTauwKdWxkiexEQwfuWnZwfP41h2w AEeOAv7vjAKa2esN4LmroDCYuaqD4J2jCE+zho0uhQ2Ifb78rBh2sU4I0RO8Wa/Xtr6K hCUJSEF3XdBG15n2H7Lz5F/Q4ERP/2BbngSrKhVdb/gBVhxC1LsauFCVZ+mmlE78YNqd ER1qUMleNltMHGenomqo//PBOXRp0JIWJNRQzW8vTqkCIEMEA6p+mTIadX5UiQKG0Xau aX9oFqASoL1G5bDoR+8viSYzoJMM+gOItbDKzSLp5855yhPmB40LSYLNjn64s3G6mADk 7oNg== X-Forwarded-Encrypted: i=1; AKwUvBy/GMfPRUC+hUqOKiRW6sDDei6Z0jJ7ynz1LUiVykG2iSVLGIeTI9lh0Dds4+V/4BX8/Ayb4Q1ZG0UH9wo=@vger.kernel.org X-Gm-Message-State: AFuF++n2InZh2C8y9VNgI9eKgIhJFiW/Mq6J86GVC6JOtNFu1wRM2GBN lc5PmoEG1j9RLCQ+unwIUsZugsAUDmGcQ+QWMytB7fjEAj212odGfgOkyIZgHJbzYf0= X-Gm-Gg: AYBFou1aYrtpOO2L8Is3cxbbjeSL8yxLlOWt0YfslHqBgLir3gI23WTgaiC+JznHu5Z Ioj2UP0J2LynjMiYF9PcyQERl2dWNYnrI5e1M2mKvURlQUcgjolKYXBJRJgPJN9B1GG/xV4pdg0 MtzAVIL3zWDxst5SmGqYgmAeQqWTr2l9k/opzHV4FM+y9MDSVBldffkfh4hz5OoUeaDZT2DXBFg qTJZeqvgBPcIP5sp4r5d//z4lhbwVzQPUUhjBc54cn9SF+E8dD0yRMSKK3ZqHaEQUA90+eGWHYj zReNHbVX2bUxkNdHreuVT63fCV2vgNiHnu1iNksKU6/U6frh6kmuOzmBOdwoVnN6kYOmIyA2OLW zis2+QhRcfEgO9UUmgrAre1dWGP3UP2vM9AEKnRGOjMhneygUk9dWMQgmaWLqJpRl+yGvJQQLj1 0HSZb0oGJvjAGucil7Y6IsqgF4CID/xnO6hHmJaEINIZsnBu7b1mux8Rufuo77RGIkW/amWDg= X-Received: by 2002:a05:6000:186b:b0:487:81c:b5e2 with SMTP id ffacd0b85a97d-4871e244c0cmr2606562f8f.5.1789725329175; Fri, 18 Sep 2026 02:55:29 -0700 (PDT) Received: from localhost ([195.94.147.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4871ff3a928sm3077528f8f.13.2026.09.18.02.55.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Sep 2026 02:55:28 -0700 (PDT) From: Andrea della Porta To: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , linux-pwm@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Florian Fainelli , Broadcom internal kernel review list , Andrea della Porta , devicetree@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Naushir Patuck , Stanimir Varbanov , mbrugger@suse.com, Sean Young , Julian Braha , "Gary Guo" , Christophe JAILLET Subject: [PATCH v9 3/3] arm64: dts: broadcom: rpi-5: Add RP1 PWM node Date: Fri, 18 Sep 2026 11:59:02 +0200 Message-ID: <504b6c3403b0cdc1731d3dca735d5a07450e80e2.1789724999.git.andrea.porta@suse.com> X-Mailer: git-send-email 2.51.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 Content-Type: text/plain; charset="utf-8" From: Stanimir Varbanov The RP1 chipset used on the Raspberry Pi 5 features an integrated PWM controller to drive the cooling fan. Add the corresponding DT node for this PWM controller. Signed-off-by: Stanimir Varbanov Co-developed-by: Andrea della Porta Signed-off-by: Andrea della Porta --- arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 12 ++++++++++++ arch/arm64/boot/dts/broadcom/rp1-common.dtsi | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/= boot/dts/broadcom/bcm2712-rpi-5-b.dts index 0fc57e72632ed..748be8f1ee9e2 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts @@ -64,6 +64,12 @@ phy1: ethernet-phy@1 { }; =20 &rp1_gpio { + fan_pwm_default_state: fan-pwm-default-state { + function =3D "pwm1"; + pins =3D "gpio45"; + bias-pull-down; + }; + usb_vbus_default_state: usb-vbus-default-state { function =3D "vbus1"; groups =3D "vbus1"; @@ -94,6 +100,12 @@ &rp1_i2c6 { pinctrl-names =3D "default"; }; =20 +&rp1_pwm1 { + pinctrl-0 =3D <&fan_pwm_default_state>; + pinctrl-names =3D "default"; + status =3D "okay"; +}; + &rp1_usb0 { pinctrl-0 =3D <&usb_vbus_default_state>; pinctrl-names =3D "default"; diff --git a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi b/arch/arm64/boot= /dts/broadcom/rp1-common.dtsi index 16f5359395835..df4c2d09c8d34 100644 --- a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi +++ b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi @@ -99,7 +99,16 @@ rp1_i2c6: i2c@40088000 { clocks =3D <&rp1_clocks RP1_CLK_SYS>; i2c-scl-rising-time-ns =3D <65>; i2c-scl-falling-time-ns =3D <100>; + status =3D "disabled"; + }; =20 + rp1_pwm1: pwm@4009c000 { + compatible =3D "raspberrypi,rp1-pwm"; + reg =3D <0x00 0x4009c000 0x0 0x100>; + clocks =3D <&rp1_clocks RP1_CLK_PWM1>; + assigned-clocks =3D <&rp1_clocks RP1_CLK_PWM1>; + assigned-clock-rates =3D <50000000>; + #pwm-cells =3D <3>; status =3D "disabled"; }; =20 --=20 2.35.3