2 * Copyright 2016 Google Inc.
4 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/arch/clock.h>
12 #include <asm/arch/pwm.h>
14 DECLARE_GLOBAL_DATA_PTR
;
16 struct tegra_pwm_priv
{
17 struct pwm_ctlr
*regs
;
20 static int tegra_pwm_set_config(struct udevice
*dev
, uint channel
,
21 uint period_ns
, uint duty_ns
)
23 struct tegra_pwm_priv
*priv
= dev_get_priv(dev
);
24 struct pwm_ctlr
*regs
= priv
->regs
;
30 debug("%s: Configure '%s' channel %u\n", __func__
, dev
->name
, channel
);
31 /* We ignore the period here and just use 32KHz */
32 clock_start_periph_pll(PERIPH_ID_PWM
, CLOCK_ID_SFROM32KHZ
, 32768);
34 pulse_width
= duty_ns
* 255 / period_ns
;
36 reg
= pulse_width
<< PWM_WIDTH_SHIFT
;
37 reg
|= 1 << PWM_DIVIDER_SHIFT
;
38 writel(reg
, ®s
[channel
].control
);
39 debug("%s: pulse_width=%u\n", __func__
, pulse_width
);
44 static int tegra_pwm_set_enable(struct udevice
*dev
, uint channel
, bool enable
)
46 struct tegra_pwm_priv
*priv
= dev_get_priv(dev
);
47 struct pwm_ctlr
*regs
= priv
->regs
;
51 debug("%s: Enable '%s' channel %u\n", __func__
, dev
->name
, channel
);
52 clrsetbits_le32(®s
[channel
].control
, PWM_ENABLE_MASK
,
53 enable
? PWM_ENABLE_MASK
: 0);
58 static int tegra_pwm_ofdata_to_platdata(struct udevice
*dev
)
60 struct tegra_pwm_priv
*priv
= dev_get_priv(dev
);
62 priv
->regs
= (struct pwm_ctlr
*)dev_read_addr(dev
);
67 static const struct pwm_ops tegra_pwm_ops
= {
68 .set_config
= tegra_pwm_set_config
,
69 .set_enable
= tegra_pwm_set_enable
,
72 static const struct udevice_id tegra_pwm_ids
[] = {
73 { .compatible
= "nvidia,tegra124-pwm" },
74 { .compatible
= "nvidia,tegra20-pwm" },
78 U_BOOT_DRIVER(tegra_pwm
) = {
81 .of_match
= tegra_pwm_ids
,
82 .ops
= &tegra_pwm_ops
,
83 .ofdata_to_platdata
= tegra_pwm_ofdata_to_platdata
,
84 .priv_auto_alloc_size
= sizeof(struct tegra_pwm_priv
),