[PATCH v17 0/2] Microchip Soft IP corePWM driver
Conor Dooley
conor.dooley at microchip.com
Fri Apr 21 02:27:08 PDT 2023
Hello,
Yet another version of this driver :)
This time around I've implemented Uwe's simplified method for
calculating the prescale & period_steps. For low values of prescale it
makes for much worse approximations of the period, but as the period
increases with respect to the that of the pwm's underlying clock there
is mostly no different in the approximations.
For this (and the last revision) I mostly did my testing using a script,
rather than in hardware, but the pwm debug stuff didn't have any
complaints, and the values I did check by hand all looked fine.
Didn't work for me last time I tried it, but I did push it out for the
LKP bot again this time and it was happy. Hopefully no repeat of it
finding some division it doesn't like after telling me it was fine on
my branch!
Thanks,
Conor.
Changes since v16:
- only write out the period immediately before the duty cycle to avoid
potentially racing against the period counter resetting
- update some comments that had bitrotted
- use Uwe's simple method for calculating period/duty & reject any
period for which tmp < 255
Changes since v15:
- calculate prescale modulus without using %
Changes since v14:
- change period_steps calculation logic to correctly handle the cases
where tmp % (254 + 1) == 0, by swapping implicit truncation for
explicit rounding upwards and subtracting zero
- special case periods < 1/clk_rate & add a note in limitations about
this, although I think this issue wasn't present prior to v15's
changes
- check for smaller suitable values of prescale, which picks the "more
correct" value in about half of all cases, particularly those where
tmp is large.
- explain what I mean by the "optimal" values for prescale/period steps
re-fix use of defines
- add a comment about how sync_upd mode works
- make the use of period_steps and prescale consistently refer to the
register values rather than, in comments, using these to mean the
resulting values after 1 has been added
- drop the PREG_TO_VAL() macro, as most of its users are now gone & it
only added to the register value versus "real" value problem
- report pwmchip_add() failures
Changes since v13:
- couple bits of cleanup to apply_locked(), suggested by Uwe
- move the overhead waiting for a change to be applied, for channels
with shadow registers, to subsequent calls to apply(). This has the
benefit of only waiting when two calls to apply() are close in time
rather than eating the delay in every call.
Changes since v11:
- swap a "bare" multiply & divide for the corresponding helper to
prevent overflow
- factor out duplicate clk rate acquisition & period calculation
- make the period calculation return void by checking the validity of
the clock rate in the caller
- drop the binding & dt patch, they're on-track for v6.2 via my tree
Changes since v10:
- reword some comments
- try to assign the period if a disable is requested
- drop a cast around a u8 -> u16 conversion
- fix a check on period_steps that should be on the hw_ variant
- split up the period calculation in get_state() to fix the result on
32 bit
- add a rate variable in get_state() to only call get_rate() once
- redo the locking as suggested to make it more straightforward.
- stop checking for enablement in get_state() that was working around
intended behaviour of the sysfs interface
Changes since v9:
- fixed the missing unlock that Dan reported
Changes since v8:
- fixed a(nother) raw 64 bit division (& built it for riscv32!)
- added a check to make sure we don't try to sleep for 0 us
Changes since v7:
- rebased on 6.0-rc1
- reworded comments you highlighted in v7
- fixed the overkill sleeping
- removed the unused variables in calc_duty
- added some extra comments to explain behaviours you questioned in v7
- make the mutexes un-interruptible
- fixed added the 1s you suggested for the if(period_locked) logic
- added setup of the channel_enabled shadowing
- fixed the period reporting for the negedge == posedge case in
get_state() I had to add the enabled check, as otherwise it broke
setting the period for the first time out of reset.
- added a test for invalid PERIOD_STEPS values, in which case we abort
if we cannot fix the period
Changes from v6:
- Dropped an unused variable that I'd missed
- Actually check the return values of the mutex lock()s
- Re-rebased on -next for the MAINTAINERS patch (again...)
Changes from v5:
- switched to a mutex b/c we must sleep with the lock taken
- simplified the locking in apply() and added locking to get_state()
- reworked apply() as requested
- removed the loop in the period calculation (thanks Uwe!)
- add a copy of the enable registers in the driver to save on reads.
- remove the second (useless) write to sync_update
- added some missing rounding in get_state()
- couple other minor cleanups as requested in:
https://lore.kernel.org/linux-riscv/20220709160206.cw5luo7kxdshoiua@pengutronix.de/
Changes from v4:
- dropped some accidentally added files
Changes before v4:
https://lore.kernel.org/linux-pwm/20220721172109.941900-1-mail@conchuod.ie
Conor Dooley (2):
pwm: add microchip soft ip corePWM driver
MAINTAINERS: add pwm to PolarFire SoC entry
MAINTAINERS | 1 +
drivers/pwm/Kconfig | 10 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-microchip-core.c | 507 +++++++++++++++++++++++++++++++
4 files changed, 519 insertions(+)
create mode 100644 drivers/pwm/pwm-microchip-core.c
--
2.39.2
More information about the linux-riscv
mailing list