Home | History | Annotate | Download | only in pwm
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright 2016 Google Inc.
      4  */
      5 
      6 #include <common.h>
      7 #include <dm.h>
      8 #include <pwm.h>
      9 #include <asm/io.h>
     10 #include <asm/arch/clock.h>
     11 #include <asm/arch/pwm.h>
     12 
     13 struct tegra_pwm_priv {
     14 	struct pwm_ctlr *regs;
     15 };
     16 
     17 static int tegra_pwm_set_config(struct udevice *dev, uint channel,
     18 				uint period_ns, uint duty_ns)
     19 {
     20 	struct tegra_pwm_priv *priv = dev_get_priv(dev);
     21 	struct pwm_ctlr *regs = priv->regs;
     22 	uint pulse_width;
     23 	u32 reg;
     24 
     25 	if (channel >= 4)
     26 		return -EINVAL;
     27 	debug("%s: Configure '%s' channel %u\n", __func__, dev->name, channel);
     28 	/* We ignore the period here and just use 32KHz */
     29 	clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, 32768);
     30 
     31 	pulse_width = duty_ns * 255 / period_ns;
     32 
     33 	reg = pulse_width << PWM_WIDTH_SHIFT;
     34 	reg |= 1 << PWM_DIVIDER_SHIFT;
     35 	writel(reg, &regs[channel].control);
     36 	debug("%s: pulse_width=%u\n", __func__, pulse_width);
     37 
     38 	return 0;
     39 }
     40 
     41 static int tegra_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
     42 {
     43 	struct tegra_pwm_priv *priv = dev_get_priv(dev);
     44 	struct pwm_ctlr *regs = priv->regs;
     45 
     46 	if (channel >= 4)
     47 		return -EINVAL;
     48 	debug("%s: Enable '%s' channel %u\n", __func__, dev->name, channel);
     49 	clrsetbits_le32(&regs[channel].control, PWM_ENABLE_MASK,
     50 			enable ? PWM_ENABLE_MASK : 0);
     51 
     52 	return 0;
     53 }
     54 
     55 static int tegra_pwm_ofdata_to_platdata(struct udevice *dev)
     56 {
     57 	struct tegra_pwm_priv *priv = dev_get_priv(dev);
     58 
     59 	priv->regs = (struct pwm_ctlr *)dev_read_addr(dev);
     60 
     61 	return 0;
     62 }
     63 
     64 static const struct pwm_ops tegra_pwm_ops = {
     65 	.set_config	= tegra_pwm_set_config,
     66 	.set_enable	= tegra_pwm_set_enable,
     67 };
     68 
     69 static const struct udevice_id tegra_pwm_ids[] = {
     70 	{ .compatible = "nvidia,tegra124-pwm" },
     71 	{ .compatible = "nvidia,tegra20-pwm" },
     72 	{ }
     73 };
     74 
     75 U_BOOT_DRIVER(tegra_pwm) = {
     76 	.name	= "tegra_pwm",
     77 	.id	= UCLASS_PWM,
     78 	.of_match = tegra_pwm_ids,
     79 	.ops	= &tegra_pwm_ops,
     80 	.ofdata_to_platdata	= tegra_pwm_ofdata_to_platdata,
     81 	.priv_auto_alloc_size	= sizeof(struct tegra_pwm_priv),
     82 };
     83