Skip to content

Commit

Permalink
hw/misc: Add a PWM module for NPCM7XX
Browse files Browse the repository at this point in the history
The PWM module is part of NPCM7XX module. Each NPCM7XX module has two
identical PWM modules. Each module contains 4 PWM entries. Each PWM has
two outputs: frequency and duty_cycle. Both are computed using inputs
from software side.

This module does not model detail pulse signals since it is expensive.
It also does not model interrupts and watchdogs that are dependant on
the detail models. The interfaces for these are left in the module so
that anyone in need for these functionalities can implement on their
own.

The user can read the duty cycle and frequency using qom-get command.

Reviewed-by: Havard Skinnemoen <[email protected]>
Reviewed-by: Tyrone Ting <[email protected]>
Signed-off-by: Hao Wu <[email protected]>
Message-id: [email protected]
Reviewed-by: Peter Maydell <[email protected]>
Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
haowu4682 authored and pm215 committed Jan 12, 2021
1 parent 77c05b0 commit 1e943c5
Show file tree
Hide file tree
Showing 7 changed files with 689 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/system/arm/nuvoton.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Supported devices
* USB host (USBH)
* GPIO controller
* Analog to Digital Converter (ADC)
* Pulse Width Modulation (PWM)

Missing devices
---------------
Expand All @@ -61,7 +62,6 @@ Missing devices
* Peripheral SPI controller (PSPI)
* SD/MMC host
* PECI interface
* Pulse Width Modulation (PWM)
* Tachometer
* PCI and PCIe root complex and bridges
* VDM and MCTP support
Expand Down
26 changes: 24 additions & 2 deletions hw/arm/npcm7xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ enum NPCM7xxInterrupt {
NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
NPCM7XX_EHCI_IRQ = 61,
NPCM7XX_OHCI_IRQ = 62,
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
NPCM7XX_GPIO0_IRQ = 116,
NPCM7XX_GPIO1_IRQ,
NPCM7XX_GPIO2_IRQ,
Expand Down Expand Up @@ -144,6 +146,12 @@ static const hwaddr npcm7xx_fiu3_flash_addr[] = {
0xb8000000, /* CS3 */
};

/* Register base address for each PWM Module */
static const hwaddr npcm7xx_pwm_addr[] = {
0xf0103000,
0xf0104000,
};

static const struct {
hwaddr regs_addr;
uint32_t unconnected_pins;
Expand Down Expand Up @@ -353,6 +361,10 @@ static void npcm7xx_init(Object *obj)
object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i],
TYPE_NPCM7XX_FIU);
}

for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
}
}

static void npcm7xx_realize(DeviceState *dev, Error **errp)
Expand Down Expand Up @@ -513,6 +525,18 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci), 0,
npcm7xx_irq(s, NPCM7XX_OHCI_IRQ));

/* PWM Modules. Cannot fail. */
QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pwm_addr) != ARRAY_SIZE(s->pwm));
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pwm[i]);

qdev_connect_clock_in(DEVICE(&s->pwm[i]), "clock", qdev_get_clock_out(
DEVICE(&s->clk), "apb3-clock"));
sysbus_realize(sbd, &error_abort);
sysbus_mmio_map(sbd, 0, npcm7xx_pwm_addr[i]);
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
}

/*
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
* specified, but this is a programming error.
Expand Down Expand Up @@ -580,8 +604,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
create_unimplemented_device("npcm7xx.pwm[0]", 0xf0103000, 4 * KiB);
create_unimplemented_device("npcm7xx.pwm[1]", 0xf0104000, 4 * KiB);
create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB);
create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB);
create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB);
Expand Down
1 change: 1 addition & 0 deletions hw/misc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
'npcm7xx_clk.c',
'npcm7xx_gcr.c',
'npcm7xx_pwm.c',
'npcm7xx_rng.c',
))
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files(
Expand Down
Loading

0 comments on commit 1e943c5

Please sign in to comment.