| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* Intel Low Power Subsystem PWM controller driver */ |
| 3 | |
| 4 | #ifndef __PLATFORM_DATA_X86_PWM_LPSS_H |
| 5 | #define __PLATFORM_DATA_X86_PWM_LPSS_H |
| 6 | |
| 7 | #include <linux/types.h> |
| 8 | |
| 9 | struct device; |
| 10 | |
| 11 | struct pwm_lpss_chip; |
| 12 | |
| 13 | struct pwm_lpss_boardinfo { |
| 14 | unsigned long clk_rate; |
| 15 | unsigned int npwm; |
| 16 | unsigned long base_unit_bits; |
| 17 | /* |
| 18 | * NOTE: |
| 19 | * Intel Broxton, Apollo Lake, and Gemini Lake have different programming flow. |
| 20 | * |
| 21 | * Initial Enable or First Activation |
| 22 | * 1. Program the base unit and on time divisor values. |
| 23 | * 2. Set the software update bit. |
| 24 | * 3. Poll in a loop on the PWMCTRL bit until software update bit is cleared.+ |
| 25 | * 4. Enable the PWM output by setting PWM Enable. |
| 26 | * 5. Repeat the above steps for the next PWM Module. |
| 27 | * |
| 28 | * Dynamic update while PWM is Enabled |
| 29 | * 1. Program the base unit and on-time divisor values. |
| 30 | * 2. Set the software update bit. |
| 31 | * 3. Repeat the above steps for the next PWM module. |
| 32 | * |
| 33 | * + After setting PWMCTRL register's SW update bit, hardware automatically |
| 34 | * deasserts the SW update bit after a brief delay. It was observed that |
| 35 | * setting of PWM enable is typically done via read-modify-write of the PWMCTRL |
| 36 | * register. If there is no/little delay between setting software update bit |
| 37 | * and setting enable bit via read-modify-write, it is possible that the read |
| 38 | * could return with software enable as 1. In that case, the last write to set |
| 39 | * enable to 1 could also set sw_update to 1. If this happens, sw_update gets |
| 40 | * stuck and the driver code can hang as it explicitly waits for sw_update bit |
| 41 | * to be 0 after setting the enable bit to 1. To avoid this race condition, |
| 42 | * SW should poll on the software update bit to make sure that it is 0 before |
| 43 | * doing the read-modify-write to set the enable bit to 1. |
| 44 | * |
| 45 | * Also, we noted that if sw_update bit was set in step #1 above then when it |
| 46 | * is set again in step #2, sw_update bit never gets cleared and the flow hangs. |
| 47 | * As such, we need to make sure that sw_update bit is 0 when doing step #1. |
| 48 | */ |
| 49 | bool bypass; |
| 50 | /* |
| 51 | * On some devices the _PS0/_PS3 AML code of the GPU (GFX0) device |
| 52 | * messes with the PWM0 controllers state, |
| 53 | */ |
| 54 | bool other_devices_aml_touches_pwm_regs; |
| 55 | }; |
| 56 | |
| 57 | struct pwm_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base, |
| 58 | const struct pwm_lpss_boardinfo *info); |
| 59 | |
| 60 | #endif /* __PLATFORM_DATA_X86_PWM_LPSS_H */ |
| 61 | |