Pulse Width Modulation peripheral
PWM
The PWM (pulse width modulation) peripheral is used to control the brightness of the display backlight. On the JZ4730, there are two PWM channels whose registers are located from 0x10050000 and 0x10051000 respectively.
PWM Registers
The registers appearing at an offset relative to each base location are as follows:
Register | Offset | Purpose |
---|---|---|
CTR | 0x00 | Control |
PER | 0x04 | Period |
DUT | 0x08 | Duty |
CTR
The control register (CTR) is arranged as follows:
Bits | Purpose |
---|---|
7 | Enable |
6 | Abrupt shutdown |
5..0 | Prescale |
The value stored in the prescale field is the frequency divider applied to EXCLK minus one. Thus, a stored value of zero yields a divider of one and a resulting PWM frequency of EXCLK, and the maximum stored value of 63 yields a divider of 64 and a resulting PWM frequency of EXCLK/64.
PER
The period register (PER) is arranged as follows:
Bits | Purpose |
---|---|
15..10 | (Reserved) |
9..0 | Period |
DUT
The duty register (DUT) is arranged as follows:
Bits | Purpose |
---|---|
15..11 | (Reserved) |
10 | Full duty |
9..0 | Duty |
Where full duty is set, the PWM output remains high at all times. Otherwise, with full duty cleared, the duty value determines the number of PWM clock cycles during the period when the PWM output is high, with the output being driven low for (period - duty) cycles.
(The documentation actually contradicts the above description of the number of high cycles with respect to the duty value, but the diagram appears to indicate the actual behaviour.)
Notes
The prescaler seems to be a simple quantity, not a 4**n progression as seen in the JZ4740 TCSR:PRESCALE field.
Thus, the PWM frequency can be calculated as follows, given observed values:
PWM frequency = clock frequency / prescaler / period count
= 3686400Hz / 64 / 300
= 192Hz
The above formula can be rewritten as follows:
PWM frequency = clock frequency / (prescaler * period count)
clock period * prescaler * period count = PWM period
prescaler * period count = PWM period / clock period
prescaler * period count = PWM period * clock frequency
With the prescaler and period count apparently acting together as a larger quantity, the prescaler needs populating when the period count would otherwise exceed the limit of its field.
Zero Field Values
The period and prescale fields may use zero to represent a value of one, with the stored values therefore being one lower than the desired values. In other words, a period of 300 would be represented by storing 299 in the period register.
Various magic values are found in old driver code, but no documentation exists to confirm whether this representation scheme is imposed. Other Ingenic SoCs do appear to use such schemes, however.
Resources
In modern kernels, the following files are pertinent:
- drivers/pwm/pwm-jz4730.c