~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/arch/arm/cpu/armv7/tegra20/pwm.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Tegra2 pulse width frequency modulator definitions
 
3
 *
 
4
 * Copyright (c) 2011 The Chromium OS Authors.
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
 
 
9
#include <common.h>
 
10
#include <fdtdec.h>
 
11
#include <asm/io.h>
 
12
#include <asm/arch/clock.h>
 
13
#include <asm/arch/pwm.h>
 
14
 
 
15
struct pwm_info {
 
16
        struct pwm_ctlr *pwm;           /* Registers for our pwm controller */
 
17
        int pwm_node;                   /* PWM device tree node */
 
18
} local;
 
19
 
 
20
void pwm_enable(unsigned channel, int rate, int pulse_width, int freq_divider)
 
21
{
 
22
        u32 reg;
 
23
 
 
24
        assert(channel < PWM_NUM_CHANNELS);
 
25
 
 
26
        /* TODO: Can we use clock_adjust_periph_pll_div() here? */
 
27
        clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, rate);
 
28
 
 
29
        reg = PWM_ENABLE_MASK;
 
30
        reg |= pulse_width << PWM_WIDTH_SHIFT;
 
31
        reg |= freq_divider << PWM_DIVIDER_SHIFT;
 
32
        writel(reg, &local.pwm[channel].control);
 
33
        debug("%s: channel=%d, rate=%d\n", __func__, channel, rate);
 
34
}
 
35
 
 
36
int pwm_request(const void *blob, int node, const char *prop_name)
 
37
{
 
38
        int pwm_node;
 
39
        u32 data[3];
 
40
 
 
41
        if (fdtdec_get_int_array(blob, node, prop_name, data,
 
42
                        ARRAY_SIZE(data))) {
 
43
                debug("%s: Cannot decode PWM property '%s'\n", __func__,
 
44
                      prop_name);
 
45
                return -1;
 
46
        }
 
47
 
 
48
        pwm_node = fdt_node_offset_by_phandle(blob, data[0]);
 
49
        if (pwm_node != local.pwm_node) {
 
50
                debug("%s: PWM property '%s' phandle %d not recognised"
 
51
                      "- expecting %d\n", __func__, prop_name, data[0],
 
52
                      local.pwm_node);
 
53
                return -1;
 
54
        }
 
55
        if (data[1] >= PWM_NUM_CHANNELS) {
 
56
                debug("%s: PWM property '%s': invalid channel %u\n", __func__,
 
57
                      prop_name, data[1]);
 
58
                return -1;
 
59
        }
 
60
 
 
61
        /*
 
62
         * TODO: We could maintain a list of requests, but it might not be
 
63
         * worth it for U-Boot.
 
64
         */
 
65
        return data[1];
 
66
}
 
67
 
 
68
int pwm_init(const void *blob)
 
69
{
 
70
        local.pwm_node = fdtdec_next_compatible(blob, 0,
 
71
                                                COMPAT_NVIDIA_TEGRA20_PWM);
 
72
        if (local.pwm_node < 0) {
 
73
                debug("%s: Cannot find device tree node\n", __func__);
 
74
                return -1;
 
75
        }
 
76
 
 
77
        local.pwm = (struct pwm_ctlr *)fdtdec_get_addr(blob, local.pwm_node,
 
78
                                                       "reg");
 
79
        if (local.pwm == (struct pwm_ctlr *)FDT_ADDR_T_NONE) {
 
80
                debug("%s: Cannot find pwm reg address\n", __func__);
 
81
                return -1;
 
82
        }
 
83
        debug("Tegra PWM at %p, node %d\n", local.pwm, local.pwm_node);
 
84
 
 
85
        return 0;
 
86
}