{"id":2225190,"url":"http://patchwork.ozlabs.org/api/1.1/covers/2225190/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pwm/cover/20260420-rk3576-pwm-v4-0-421738c7bf28@collabora.com/","project":{"id":38,"url":"http://patchwork.ozlabs.org/api/1.1/projects/38/?format=json","name":"Linux PWM development","link_name":"linux-pwm","list_id":"linux-pwm.vger.kernel.org","list_email":"linux-pwm@vger.kernel.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260420-rk3576-pwm-v4-0-421738c7bf28@collabora.com>","date":"2026-04-20T13:35:18","name":"[v4,0/5] Add Rockchip RK3576 PWM Support Through MFPWM","submitter":{"id":90188,"url":"http://patchwork.ozlabs.org/api/1.1/people/90188/?format=json","name":"Nicolas Frattaroli","email":"nicolas.frattaroli@collabora.com"},"mbox":"http://patchwork.ozlabs.org/project/linux-pwm/cover/20260420-rk3576-pwm-v4-0-421738c7bf28@collabora.com/mbox/","series":[{"id":500618,"url":"http://patchwork.ozlabs.org/api/1.1/series/500618/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pwm/list/?series=500618","date":"2026-04-20T13:35:22","name":"Add Rockchip RK3576 PWM Support Through MFPWM","version":4,"mbox":"http://patchwork.ozlabs.org/series/500618/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/covers/2225190/comments/","headers":{"Return-Path":"\n <linux-pwm+bounces-8646-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pwm@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com\n header.a=rsa-sha256 header.s=zohomail header.b=DB4kL23K;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=104.64.211.4; helo=sin.lore.kernel.org;\n envelope-from=linux-pwm+bounces-8646-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=collabora.com\n header.i=nicolas.frattaroli@collabora.com header.b=\"DB4kL23K\"","smtp.subspace.kernel.org;\n arc=pass smtp.client-ip=136.143.188.112","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=collabora.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=collabora.com"],"Received":["from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fzpnw3FWzz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 01:10:28 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id C312A334C089\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 20 Apr 2026 14:41:40 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id D59223B5851;\n\tMon, 20 Apr 2026 13:36:43 +0000 (UTC)","from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com\n [136.143.188.112])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id C1DD83B47D5;\n\tMon, 20 Apr 2026 13:36:41 +0000 (UTC)","by mx.zohomail.com with SMTPS id 1776692160029395.011572346355;\n\tMon, 20 Apr 2026 06:36:00 -0700 (PDT)"],"ARC-Seal":["i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776692203; cv=pass;\n b=QNwubj/CzuP7k9dPcqJOpb+BTgiqFX1TuulxIO6zUBikmI4rDU1Wab8KOhe+3J8F3ssDrSUZzY2/7bvD951LzVqkbW9ymdnU5SYxPGWEcKHdvd7Cd5pn7s52rc/4mWSIJMuUjhy8sixWUGumkqd0hZ6N2oFuLnDbisQTvGypG88=","i=1; a=rsa-sha256; t=1776692162; cv=none;\n\td=zohomail.com; s=zohoarc;\n\tb=c9zZFaXzcvREJwz0wSqQ9pRnTiWhjOvVPVDLirkf/i82Spe+e9VG1/vmMIt09CPGNs3ozySbTwVmC9afiVyXtSpY+XYU+EN2EHTrIwQQffLP3jDSayNOARU1oV5BBa9WwN9Ea5y4kbMM5vjVeOvr2tJTxonEjETSZsT4RrQ6ynI="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776692203; c=relaxed/simple;\n\tbh=KFumLSOaHpSenecvrbbACUEdI+0vNQq1Syc+iq6KAgc=;\n\th=From:Subject:Date:Message-Id:MIME-Version:Content-Type:To:Cc;\n b=RqBWCvp5RPX09FVqwAt8XziAIGfWIEnuiHdzB4GvFL1luegopG22hzfWa8LVS4RWoFDoFZdbYWz8EUANUffPPNjDnkv9NlD3ApXeRcCda5BvuodKlmR2gBEr0mv/0Q5ELEYobn3dSJUDMFchnu4exlgYl5vJdby47Q85VlUQZOg=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com;\n s=zohoarc;\n\tt=1776692162;\n h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To;\n\tbh=o/hAKPfN8TMW+uD8YQyiZTajFu7O0Cud/JgnJ6Wj6Tg=;\n\tb=FoQ4Mzz0yS+pRNZyLKMrQewXUDbpMkzd7pPQgs+x7G2/Zy5VyWPzxRs1Xf7a3LxYlP5LSHsuC6SlsITO1/jV15T9wm2tWI6B5UqSAfqqkzCRFOiMRdQDO/xUxhXvQGAt457k0wCZdFCdHKTcgYokYXmUMoT01qiUoYPTpOkNYW4="],"ARC-Authentication-Results":["i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=collabora.com;\n spf=pass smtp.mailfrom=collabora.com;\n dkim=pass (1024-bit key) header.d=collabora.com\n header.i=nicolas.frattaroli@collabora.com header.b=DB4kL23K;\n arc=pass smtp.client-ip=136.143.188.112","i=1; mx.zohomail.com;\n\tdkim=pass  header.i=collabora.com;\n\tspf=pass  smtp.mailfrom=nicolas.frattaroli@collabora.com;\n\tdmarc=pass header.from=<nicolas.frattaroli@collabora.com>"],"DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1776692162;\n\ts=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com;\n\th=From:From:Subject:Subject:Date:Date:Message-Id:Message-Id:MIME-Version:Content-Type:Content-Transfer-Encoding:To:To:Cc:Cc:Reply-To;\n\tbh=o/hAKPfN8TMW+uD8YQyiZTajFu7O0Cud/JgnJ6Wj6Tg=;\n\tb=DB4kL23K8D1cf/ohw6LzSMl0Msm95Cokhwu7FmT70WAT7bdnTQzcghRn8jfyQGS6\n\tdWMwVB9G6jSJn4pvhIVLSNG7QMkjOkDwXt2JZj+pkDl5Yff4lFZ5QGCcqryDSaPgyP7\n\t6oDOeObrTtCuE4ZxqFpFEqw99E9OUlSjyk1CBONY=","From":"Nicolas Frattaroli <nicolas.frattaroli@collabora.com>","Subject":"[PATCH v4 0/5] Add Rockchip RK3576 PWM Support Through MFPWM","Date":"Mon, 20 Apr 2026 15:35:18 +0200","Message-Id":"<20260420-rk3576-pwm-v4-0-421738c7bf28@collabora.com>","Precedence":"bulk","X-Mailing-List":"linux-pwm@vger.kernel.org","List-Id":"<linux-pwm.vger.kernel.org>","List-Subscribe":"<mailto:linux-pwm+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pwm+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"8bit","X-B4-Tracking":"v=1; b=H4sIAAAAAAAC/23PwU7DMAwG4FepcibIcVK37MR7IA5J6rGItdmSE\n oamvjtZh4Ahjr+l77d9FplT4Cw2zVkkLiGHONVg7hrhd3Z6YRmGmgUCtmCgk+lVtx3Jw/soDXW\n k3AADWysqOCTehtNa9vR8zYmPb7Vzvg6Fs5mlj+MY5k0z8WmWtZfAIIgL2IU8x/SxHlPUKr729\n r/3FiVBWvOAPXn0tudHH/d762Ky97V8rSr4wwnwhuOFk9HGgWcC/x/X31wB3nxddOXUGtt6p1h\n v+798WZZP2SK4BVcBAAA=","X-Change-ID":"20250407-rk3576-pwm-46761bd0deaa","To":"=?utf-8?q?Uwe_Kleine-K=C3=B6nig?= <ukleinek@kernel.org>,\n  Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,\n  Conor Dooley <conor+dt@kernel.org>, Heiko Stuebner <heiko@sntech.de>,\n  Lee Jones <lee@kernel.org>, William Breathitt Gray <wbg@kernel.org>,\n  Damon Ding <damon.ding@rock-chips.com>","Cc":"Nicolas Frattaroli <nicolas.frattaroli@collabora.com>,\n kernel@collabora.com, Jonas Karlman <jonas@kwiboo.se>,\n Alexey Charkov <alchark@gmail.com>, linux-rockchip@lists.infradead.org,\n linux-pwm@vger.kernel.org, devicetree@vger.kernel.org,\n linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,\n linux-iio@vger.kernel.org, Conor Dooley <conor.dooley@microchip.com>","X-Mailer":"b4 0.15.2"},"content":"This series introduces support for some of the functions of the new PWM\nsilicon found on Rockchip's RK3576 SoC. Due to the wide range of\nfunctionalities offered by it, including many parts which this series'\nfirst iteration does not attempt to implement for now. The drivers are\nmodelled as an MFD, with no leakage of the MFD-ness into the binding, as\nit's a Linux implementation detail.\n\nHere's some of the features of the hardware:\n- Continuous PWM output (implemented in this series)\n- One-shot/Finite repetition PWM output\n- PWM capture by counting high/low cycles (implemented in this series)\n- Sending IR transmissions in several TV remote protocols\n- Generating an interrupt based on the input being one of 16\n  user-specified values (\"Power key capture\")\n- Biphasic counter support\n- Using the hardware to measure a clock signal's frequency\n- Using the hardware to count a clock signal's pulses\n- Generating PWM output waveforms through a user-specified lookup table\n\nAs you can tell, there's a lot. I've focused on continuous PWM output\nfor now as the most important one for things like controlling fans. The\nPWM capture driver is an added bonus, because I needed at least two\ndrivers to test things. Anyone doing consumer electronic devices like\nTVs based on the RK3576 may need to do the power key stuff at some\nstage, as it can be used to wake up the SoC with an IR remote. The IR\ntransmission stuff in general may be a funny weekend project for someone\nat some point; I assume it's there so TV boxes can turn on and off TVs\nwithout needing the HDMI control stuff.\n\nAt first, I considered simply integrating support for this new IP into\nthe old pwm-rockchip driver, as the downstream vendor kernel did.\nHowever, the IP is significantly different from previous iterations.\nEspecially if the goal is to support some of the additional\nfunctionality that the new silicon brings, doing it all in a single pwm\ndriver would be untenable. Especially one that already supports other\nhardware with a way different set of registers.\n\nHence, the mfpwm pattern: each device functionality is its own driver,\nand they all get registered as MFD cells by the parent mfpwm MFD driver,\nwhich is the one that binds to the DT compatible. Each device function\ndriver then has to _acquire and _release the hardware when it needs\ncontrol of it. If some other device function is using the device\nalready, -EBUSY is returned, which the device function driver can then\nforward to the user and everyone is happy.\n\nThe PWM output driver, pwm-rockchip-v4, uses the new waveform APIs. I\nthought while writing a new driver that I might as well use the new\nAPIs.\n\nThe PWM capture driver, implemented as a counter driver, is somewhat\nprimitive, in that it doesn't make use of things like the biphasic\ncounter support or clock measuring, but it serves as a good way to\nshowcase and test the mutual exclusion that the mfpwm framework tries to\nachieve. It directly exposes the HPC/LPC counts as counters. Shoutouts\nto the counter subsystem's documentation by the way, it is some of the\nbest subsystem documentation I've come across so far, and was a great\nhelp.\n\nAll instances of the PWM controller have three clocks that they can pick\nand choose to derive the PWM signal from. One is the default PLL from\nthe CRU, one is the 24 MHz crystal oscillator (gated by the CRU), and\none is an RC oscillator (also gated by the CRU). Each PWM channel can\nswitch between these with a clock selection register in the PWM register\nrange, hence this is implemented as a clock mux.\n\nSigned-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>\n---\nChanges in v4:\n- Fix MAINTAINERS entry for mfpwm\n- Make mfpwm core driver depend on ARCH_ROCKCHIP || COMPILE_TEST\n- Remove redundant Kconfig deps from pwm output and counter\n- mfpwm core: Introduce mfpwm_get_mode\n- mfpwm core: Rename pwm out to rockchip-pwm-v4\n- mfpwm core: Remove leftover commented out code\n- pwm output: Rename to rockchip-pwm-v4\n- pwm output: Rework round_wf_tohw:\n  - Pass wf/wfhw into round_params\n  - If wfhw->period is 0, don't do the offset clamping calculation to\n    avoid underflow\n  - Return -ERANGE in a theoretical future where the clock is that high\n  - Change debug print\n- pwm output: Change fromhw debug print to conform to other PWM drivers\n- pwm output: Adjust comments at the start of the file\n- pwm output: Store rate in wfhw struct\n- pwm output: Get rid of unnecessary initialization of locals\n- pwm output: Round up in fromhw\n- pwm output: Use common is_enabled helper in read_wf\n- pwm output: put exclusive rate and clk_disable on unlikely error path\n- pwm output: Set of_node_reused on this device, rather than the parent,\n  and set its device node to the parent node\n- pwm output: Make failure to acquire PWM in probe an error rather than\n  a warning\n- pwm output: Re-do error handling in probe function to drop clock and\n  mfpwm on failure\n- counter: Get rid of enable_lock and is_enabled, read this from hw regs\n- counter: Request IRQ after setting up the counter device\n- counter: Acquire mfpwm if counter hardware is enabled at module probe\n  time\n- counter: Rework signals, synapses and counts\n- Add patch to describe the Radxa ROCK 4D's PWM-controlled fan in DT\n- Link to v3: https://lore.kernel.org/r/20251027-rk3576-pwm-v3-0-654a5cb1e3f8@collabora.com\n\nChanges in v3:\n- Move drivers to using MFD; MFPWM now lives in the mfd tree as\n  requested by Lee Jones\n- Use the new FIELD_PREP_WM16 macros, and rebase onto next-20251027\n- Get rid of some unused hardware version accessor inline functions\n- pwm-rockchip-v4 pwm output: use devm_pwmchip_add and get rid of the\n  driver remove callback that's no longer needed\n- pwm-rockchip-v4 pwm output: use the parent MFD device's OF node, so\n  that referencing the pwm node in DT works correctly (ty Heiko)\n- pwm-rockchip-v4 pwm output: add link to public TRM for the hardware in\n  comment at the start of the file\n- pwm-rockchip-v4 pwm output: Capitalise first letter in kernel messages\n- pwm-rockchip-v4 pwm output: get rid of unnecessary mul_u64_u64_div_u64\n  calls where the operands cannot produce an overflow, turning it into a\n  regular u64 division\n- pwm-rockchip-v4 pwm output: simplify round_rate functions\n- pwm-rockchip-v4 pwm output: remove redundant duty <= period check\n- pwm-rockchip-v4 pwm output: print input parameters in tohw/fromhw in\n  debug statement\n- pwm-rockchip-v4 pwm output: clarify the offset < (period - duty) thing\n  being dictated by hardware with a comment in the limitations list and\n  near where the check is\n- pwm-rockchip-v4 pwm output: remove pointless mfpwm_acquire/release\n  calls in the fromhw/tohw functions, as they don't actually protect\n  against anything\n- pwm-rockchip-capture counter: expose HPC and LPC directly, and fire a\n  change-of-state event on the appropriate channel on interrupt\n- pwm-rockchip-capture counter: remove all the captures_left and delayed\n  worker cruft\n- pwm-rockchip-capture counter: use MFD parent's OF node\n- pwm-rockchip-capture counter: change intsts ^ clr to != and add a\n  comment explaining why there's no mask here\n- Link to v2: https://lore.kernel.org/r/20250602-rk3576-pwm-v2-0-a6434b0ce60c@collabora.com\n\nChanges in v2:\n- bindings: make osc required (as it's present in all instances of the\n  hardware I'm aware of) and add the rc clock as well. I thought it\n  wasn't present on some instances of the PWM IP due to the vendor SoC\n  dtsi, but checking the CRU made me realise those clocks do exist for\n  all instances. Did not include Conor's R-b as this constitutes a\n  substantial enough change to necessitate a re-review\n- move bitfield write-enable mask macros into bitfield.h by replacing\n  the original rockchip-specific utils header patch with a bitfield.h\n  patch.\n- mfpwm: change all instances of WARN to be dev_warn instead, as we have\n  a device pointer.\n- mfpwm: replace the ad-hoc clock mux implementation that used a sysfs\n  interface with a generic clk-mux.\n- mfpwm: add the rc clock\n- mfpwm: rename all the pwmv4_ prefixed functions to have the\n  rockchip_pwm_v4_ prefix instead\n- mfpwm: remove the pwmclk indirection, hand chosen_clk to pwmf\n- mfpwm: move to use the new bitfield macros for the WE mask\n- mfpwm: mark reg access inline functions as static to fix build errors\n- pwm-rockchip-v4 pwm output: replace mult_frac with mul_u64_u64_div_u64\n- pwm-rockchip-v4 pwm output: don't return error if parameters are out\n  of range, just set them to the maximum\n- pwm-rockchip-v4 pwm output: add rate to debug message\n- pwm-rockchip-v4 pwm output: if rate is 0 and pwm is disabled, set\n  waveform parameters to 0. The clock is expected to not have a rate in\n  this case.\n- pwm-rockchip-v4 pwm output: add pwmchip_remove in remove callback,\n  which also necessitated using chip as the platdata instead of the\n  driver private struct\n- pwm-rockchip-v4 pwm output: rework PWMV4_CTRL_UPDATE_EN since it never\n  needs to be set to 0 by the driver\n- pwm-rockchip-v4 pwm output: add a limitations list\n- pwm-rockchip-v4 pwm output: handle initial hardware state during\n  probe, enabling the pwm clock if the PWM is on and in continuous mode\n- pwm-rockchip-v4 pwm output: rename pwmv4_is_enabled to use the\n  rockchip_pwm_v4_ prefix instead\n- pwm-rockchip-v4 pwm output: remove pwmclk indirection, use clk API\n  directly\n- pwm-rockchip-v4 pwm output: no longer claim the chip as being atomic,\n  as the clk_rate_exclusive_get calls may sleep.\n- rockchip-pwm-capture counter: remove pwmclk indirection, use clk API\n  directly\n- rockchip-pwm-capture counter: replace mult_frac with\n  mul_u64_u64_div_u64\n- rockchip-pwm-capture counter: don't output periods/duty cycles if the\n  period is longer than the chosen timeout; this works around the\n  hardware cycle counter seemingly being impossible to clear\n- dts: added osc and rc to every pwm node\n- dts: reordered properties in pwm0 to be sorted\n- Link to v1: https://lore.kernel.org/r/20250408-rk3576-pwm-v1-0-a49286c2ca8e@collabora.com\n\nTo: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>\nTo: Uwe Kleine-König <ukleinek@kernel.org>\nTo: Rob Herring <robh@kernel.org>\nTo: Krzysztof Kozlowski <krzk+dt@kernel.org>\nTo: Conor Dooley <conor+dt@kernel.org>\nTo: Heiko Stuebner <heiko@sntech.de>\nTo: Lee Jones <lee@kernel.org>\nTo: William Breathitt Gray <wbg@kernel.org>\nTo: Damon Ding <damon.ding@rock-chips.com>\nCc: kernel@collabora.com\nCc: Jonas Karlman <jonas@kwiboo.se>\nCc: Alexey Charkov <alchark@gmail.com>\nCc: linux-rockchip@lists.infradead.org\nCc: linux-pwm@vger.kernel.org\nCc: devicetree@vger.kernel.org\nCc: linux-arm-kernel@lists.infradead.org\nCc: linux-kernel@vger.kernel.org\nCc: linux-iio@vger.kernel.org\n\n---\nNicolas Frattaroli (5):\n      dt-bindings: pwm: Add a new binding for rockchip,rk3576-pwm\n      mfd: Add Rockchip mfpwm driver\n      pwm: Add rockchip PWMv4 driver\n      arm64: dts: rockchip: add PWM nodes to RK3576 SoC dtsi\n      arm64: dts: rockchip: Add cooling fan to ROCK 4D\n\n .../bindings/pwm/rockchip,rk3576-pwm.yaml          |  77 ++++\n MAINTAINERS                                        |  11 +\n arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts    |  50 +++\n arch/arm64/boot/dts/rockchip/rk3576.dtsi           | 208 +++++++++\n drivers/counter/Kconfig                            |  11 +\n drivers/counter/Makefile                           |   1 +\n drivers/counter/rockchip-pwm-capture.c             | 307 ++++++++++++++\n drivers/mfd/Kconfig                                |  16 +\n drivers/mfd/Makefile                               |   1 +\n drivers/mfd/rockchip-mfpwm.c                       | 357 ++++++++++++++++\n drivers/pwm/Kconfig                                |  11 +\n drivers/pwm/Makefile                               |   1 +\n drivers/pwm/pwm-rockchip-v4.c                      | 383 +++++++++++++++++\n include/linux/mfd/rockchip-mfpwm.h                 | 470 +++++++++++++++++++++\n 14 files changed, 1904 insertions(+)\n---\nbase-commit: 77a9bb0193d790fb71c0edfc567bddc1b56fb3ff\nchange-id: 20250407-rk3576-pwm-46761bd0deaa\n\nBest regards,\n--  \nNicolas Frattaroli <nicolas.frattaroli@collabora.com>"}