ARM: tegra: Fix Tegra PWM parent clock

Default parent clock for the PWM on Tegra is a 32kHz clock and
is unable to support the requested PWM period.

Fix PWM support on Tegra20, Tegra30, Tegra114, Tegra124 and Tegra210 by
updating the parent clock for the PWM to be the PLL_P.

This commit is equivalent to Linux kernel commit:
https://lore.kernel.org/all/20221010100046.6477-1-jonathanh@nvidia.com/

Tested-by: Andreas Westman Dorcsak <hedmoo@yahoo.com> # ASUS TF T30
Tested-by: Robert Eckelmann <longnoserob@gmail.com> # ASUS TF101 T20
Tested-by: Svyatoslav Ryhel <clamor95@gmail.com> # ASUS TF201 T30
Tested-by: Thierry Reding <treding@nvidia.com> # T30 and T124
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Signed-off-by: Tom <twarren@nvidia.com>
This commit is contained in:
Svyatoslav Ryhel 2023-02-14 19:35:28 +02:00 committed by Tom
parent 678157e212
commit 23d24df34c
8 changed files with 13 additions and 11 deletions

View File

@ -312,7 +312,7 @@
};
pwm: pwm@7000a000 {
compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm";
compatible = "nvidia,tegra114-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car TEGRA114_CLK_PWM>;

View File

@ -377,7 +377,7 @@
};
pwm: pwm@7000a000 {
compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
compatible = "nvidia,tegra124-pwm", "nvidia,tegra114-pwm";
reg = <0x7000a000 0x100>;
#pwm-cells = <2>;
clocks = <&tegra_car TEGRA124_CLK_PWM>;

View File

@ -782,7 +782,7 @@ struct periph_clk_init periph_clk_init_table[] = {
{ PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH },
{ PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ },
{ PERIPH_ID_PWM, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C1, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C2, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C3, CLOCK_ID_PERIPH },

View File

@ -1208,7 +1208,7 @@ struct periph_clk_init periph_clk_init_table[] = {
{ PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH },
{ PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ },
{ PERIPH_ID_PWM, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C1, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C2, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C3, CLOCK_ID_PERIPH },

View File

@ -804,7 +804,7 @@ struct periph_clk_init periph_clk_init_table[] = {
{ PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH },
{ PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ },
{ PERIPH_ID_PWM, CLOCK_ID_PERIPH },
{ PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C1, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C2, CLOCK_ID_PERIPH },

View File

@ -1278,7 +1278,7 @@ struct periph_clk_init periph_clk_init_table[] = {
{ PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH },
{ PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ },
{ PERIPH_ID_PWM, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C1, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C2, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C3, CLOCK_ID_PERIPH },

View File

@ -884,7 +884,7 @@ struct periph_clk_init periph_clk_init_table[] = {
{ PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH },
{ PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH },
{ PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ },
{ PERIPH_ID_PWM, CLOCK_ID_PERIPH },
{ PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C1, CLOCK_ID_PERIPH },
{ PERIPH_ID_I2C2, CLOCK_ID_PERIPH },

View File

@ -20,19 +20,21 @@ static int tegra_pwm_set_config(struct udevice *dev, uint channel,
{
struct tegra_pwm_priv *priv = dev_get_priv(dev);
struct pwm_ctlr *regs = priv->regs;
const u32 pwm_max_freq = dev_get_driver_data(dev);
uint pulse_width;
u32 reg;
if (channel >= 4)
return -EINVAL;
debug("%s: Configure '%s' channel %u\n", __func__, dev->name, channel);
/* We ignore the period here and just use 32KHz */
clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, 32768);
clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_PERIPH, pwm_max_freq);
pulse_width = duty_ns * 255 / period_ns;
reg = pulse_width << PWM_WIDTH_SHIFT;
reg |= 1 << PWM_DIVIDER_SHIFT;
reg |= PWM_ENABLE_MASK;
writel(reg, &regs[channel].control);
debug("%s: pulse_width=%u\n", __func__, pulse_width);
@ -68,8 +70,8 @@ static const struct pwm_ops tegra_pwm_ops = {
};
static const struct udevice_id tegra_pwm_ids[] = {
{ .compatible = "nvidia,tegra124-pwm" },
{ .compatible = "nvidia,tegra20-pwm" },
{ .compatible = "nvidia,tegra20-pwm", .data = 48 * 1000000 },
{ .compatible = "nvidia,tegra114-pwm", .data = 408 * 1000000 },
{ }
};