xref: /qemu/include/hw/misc/npcm7xx_pwm.h (revision b355f08a)
1 /*
2  * Nuvoton NPCM7xx PWM Module
3  *
4  * Copyright 2020 Google LLC
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  */
16 #ifndef NPCM7XX_PWM_H
17 #define NPCM7XX_PWM_H
18 
19 #include "hw/clock.h"
20 #include "hw/sysbus.h"
21 #include "hw/irq.h"
22 
23 /* Each PWM module holds 4 PWM channels. */
24 #define NPCM7XX_PWM_PER_MODULE 4
25 
26 /*
27  * Number of registers in one pwm module. Don't change this without increasing
28  * the version_id in vmstate.
29  */
30 #define NPCM7XX_PWM_NR_REGS (0x54 / sizeof(uint32_t))
31 
32 /*
33  * The maximum duty values. Each duty unit represents 1/NPCM7XX_PWM_MAX_DUTY
34  * cycles. For example, if NPCM7XX_PWM_MAX_DUTY=1,000,000 and a PWM has a duty
35  * value of 100,000 the duty cycle for that PWM is 10%.
36  */
37 #define NPCM7XX_PWM_MAX_DUTY 1000000
38 
39 typedef struct NPCM7xxPWMState NPCM7xxPWMState;
40 
41 /**
42  * struct NPCM7xxPWM - The state of a single PWM channel.
43  * @module: The PWM module that contains this channel.
44  * @irq: GIC interrupt line to fire on expiration if enabled.
45  * @running: Whether this PWM channel is generating output.
46  * @inverted: Whether this PWM channel is inverted.
47  * @index: The index of this PWM channel.
48  * @cnr: The counter register.
49  * @cmr: The comparator register.
50  * @pdr: The data register.
51  * @pwdr: The watchdog register.
52  * @freq: The frequency of this PWM channel.
53  * @duty: The duty cycle of this PWM channel. One unit represents
54  *   1/NPCM7XX_MAX_DUTY cycles.
55  */
56 typedef struct NPCM7xxPWM {
57     NPCM7xxPWMState         *module;
58 
59     qemu_irq                irq;
60 
61     bool                    running;
62     bool                    inverted;
63 
64     uint8_t                 index;
65     uint32_t                cnr;
66     uint32_t                cmr;
67     uint32_t                pdr;
68     uint32_t                pwdr;
69 
70     uint32_t                freq;
71     uint32_t                duty;
72 } NPCM7xxPWM;
73 
74 /**
75  * struct NPCM7xxPWMState - Pulse Width Modulation device state.
76  * @parent: System bus device.
77  * @iomem: Memory region through which registers are accessed.
78  * @clock: The PWM clock.
79  * @pwm: The PWM channels owned by this module.
80  * @duty_gpio_out: The duty cycle of each PWM channels as a output GPIO.
81  * @ppr: The prescaler register.
82  * @csr: The clock selector register.
83  * @pcr: The control register.
84  * @pier: The interrupt enable register.
85  * @piir: The interrupt indication register.
86  */
87 struct NPCM7xxPWMState {
88     SysBusDevice parent;
89 
90     MemoryRegion iomem;
91 
92     Clock       *clock;
93     NPCM7xxPWM  pwm[NPCM7XX_PWM_PER_MODULE];
94     qemu_irq    duty_gpio_out[NPCM7XX_PWM_PER_MODULE];
95 
96     uint32_t    ppr;
97     uint32_t    csr;
98     uint32_t    pcr;
99     uint32_t    pier;
100     uint32_t    piir;
101 };
102 
103 #define TYPE_NPCM7XX_PWM "npcm7xx-pwm"
104 #define NPCM7XX_PWM(obj) \
105     OBJECT_CHECK(NPCM7xxPWMState, (obj), TYPE_NPCM7XX_PWM)
106 
107 #endif /* NPCM7XX_PWM_H */
108