hw/omap_gpio.c: Convert to qdev
Convert the OMAP GPIO module to qdev. Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com> [Riku Voipio: Fixes and restructuring patchset] Signed-off-by: Riku Voipio <riku.voipio@iki.fi> [Peter Maydell: More fixes and cleanups for upstream submission] Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
This commit is contained in:
parent
0a34f96690
commit
77831c204f
43
hw/nseries.c
43
hw/nseries.c
@ -134,9 +134,9 @@ static void n800_mmc_cs_cb(void *opaque, int line, int level)
|
||||
static void n8x0_gpio_setup(struct n800_s *s)
|
||||
{
|
||||
qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_MMC_CS_GPIO, mmc_cs[0]);
|
||||
|
||||
qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
|
||||
qemu_irq_lower(qdev_get_gpio_in(s->cpu->gpio, N800_BAT_COVER_GPIO));
|
||||
}
|
||||
|
||||
#define MAEMO_CAL_HEADER(...) \
|
||||
@ -168,8 +168,8 @@ static void n8x0_nand_setup(struct n800_s *s)
|
||||
omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
|
||||
onenand_base_unmap,
|
||||
(s->nand = onenand_init(0xec4800, 1,
|
||||
omap2_gpio_in_get(s->cpu->gpif,
|
||||
N8X0_ONENAND_GPIO)[0])));
|
||||
qdev_get_gpio_in(s->cpu->gpio,
|
||||
N8X0_ONENAND_GPIO))));
|
||||
otp_region = onenand_raw_otp(s->nand);
|
||||
|
||||
memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
|
||||
@ -180,7 +180,7 @@ static void n8x0_nand_setup(struct n800_s *s)
|
||||
static void n8x0_i2c_setup(struct n800_s *s)
|
||||
{
|
||||
DeviceState *dev;
|
||||
qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
|
||||
qemu_irq tmp_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TMP105_GPIO);
|
||||
|
||||
/* Attach the CPU on one end of our I2C bus. */
|
||||
s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
|
||||
@ -249,8 +249,8 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
|
||||
/* XXX: are the three pins inverted inside the chip between the
|
||||
* tsc and the cpu (N4111)? */
|
||||
qemu_irq penirq = NULL; /* NC */
|
||||
qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
|
||||
qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
|
||||
qemu_irq kbirq = qdev_get_gpio_in(s->cpu->gpio, N800_TSC_KP_IRQ_GPIO);
|
||||
qemu_irq dav = qdev_get_gpio_in(s->cpu->gpio, N800_TSC_TS_GPIO);
|
||||
|
||||
s->ts.chip = tsc2301_init(penirq, kbirq, dav);
|
||||
s->ts.opaque = s->ts.chip->opaque;
|
||||
@ -269,7 +269,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
|
||||
|
||||
static void n810_tsc_setup(struct n800_s *s)
|
||||
{
|
||||
qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];
|
||||
qemu_irq pintdav = qdev_get_gpio_in(s->cpu->gpio, N810_TSC_TS_GPIO);
|
||||
|
||||
s->ts.opaque = tsc2005_init(pintdav);
|
||||
s->ts.txrx = tsc2005_txrx;
|
||||
@ -361,7 +361,7 @@ static int n810_keys[0x80] = {
|
||||
|
||||
static void n810_kbd_setup(struct n800_s *s)
|
||||
{
|
||||
qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];
|
||||
qemu_irq kbd_irq = qdev_get_gpio_in(s->cpu->gpio, N810_KEYBOARD_GPIO);
|
||||
DeviceState *dev;
|
||||
int i;
|
||||
|
||||
@ -726,15 +726,15 @@ static void n8x0_dss_setup(struct n800_s *s)
|
||||
|
||||
static void n8x0_cbus_setup(struct n800_s *s)
|
||||
{
|
||||
qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
|
||||
qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
|
||||
qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
|
||||
qemu_irq dat_out = qdev_get_gpio_in(s->cpu->gpio, N8X0_CBUS_DAT_GPIO);
|
||||
qemu_irq retu_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_RETU_GPIO);
|
||||
qemu_irq tahvo_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TAHVO_GPIO);
|
||||
|
||||
CBus *cbus = cbus_init(dat_out);
|
||||
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
|
||||
|
||||
cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
|
||||
cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
|
||||
@ -743,12 +743,11 @@ static void n8x0_cbus_setup(struct n800_s *s)
|
||||
static void n8x0_uart_setup(struct n800_s *s)
|
||||
{
|
||||
CharDriverState *radio = uart_hci_init(
|
||||
omap2_gpio_in_get(s->cpu->gpif,
|
||||
N8X0_BT_HOST_WKUP_GPIO)[0]);
|
||||
qdev_get_gpio_in(s->cpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
|
||||
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_RESET_GPIO,
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_BT_RESET_GPIO,
|
||||
csrhci_pins_get(radio)[csrhci_pin_reset]);
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_WKUP_GPIO,
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_BT_WKUP_GPIO,
|
||||
csrhci_pins_get(radio)[csrhci_pin_wakeup]);
|
||||
|
||||
omap_uart_attach(s->cpu->uart[BT_UART], radio);
|
||||
@ -763,7 +762,7 @@ static void n8x0_usb_power_cb(void *opaque, int line, int level)
|
||||
|
||||
static void n8x0_usb_setup(struct n800_s *s)
|
||||
{
|
||||
qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
|
||||
qemu_irq tusb_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO);
|
||||
qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
|
||||
TUSBState *tusb = tusb6010_init(tusb_irq);
|
||||
|
||||
@ -774,7 +773,7 @@ static void n8x0_usb_setup(struct n800_s *s)
|
||||
tusb6010_sync_io(tusb), NULL, NULL, tusb);
|
||||
|
||||
s->usb = tusb;
|
||||
omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
|
||||
qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
|
||||
}
|
||||
|
||||
/* Setup done before the main bootloader starts by some early setup code
|
||||
@ -1020,7 +1019,7 @@ static void n8x0_boot_init(void *opaque)
|
||||
|
||||
/* If the machine has a slided keyboard, open it */
|
||||
if (s->kbd)
|
||||
qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N810_SLIDE_GPIO)[0]);
|
||||
qemu_irq_raise(qdev_get_gpio_in(s->cpu->gpio, N810_SLIDE_GPIO));
|
||||
}
|
||||
|
||||
#define OMAP_TAG_NOKIA_BT 0x4e01
|
||||
|
20
hw/omap.h
20
hw/omap.h
@ -683,22 +683,6 @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
|
||||
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
|
||||
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
|
||||
|
||||
/* omap1 gpio module interface */
|
||||
struct omap_gpio_s;
|
||||
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
|
||||
qemu_irq irq, omap_clk clk);
|
||||
void omap_gpio_reset(struct omap_gpio_s *s);
|
||||
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
|
||||
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
|
||||
|
||||
/* omap2 gpio interface */
|
||||
struct omap_gpif_s;
|
||||
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
|
||||
qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules);
|
||||
void omap_gpif_reset(struct omap_gpif_s *s);
|
||||
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start);
|
||||
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler);
|
||||
|
||||
struct uWireSlave {
|
||||
uint16_t (*receive)(void *opaque);
|
||||
void (*send)(void *opaque, uint16_t data);
|
||||
@ -852,7 +836,7 @@ struct omap_mpu_state_s {
|
||||
/* MPUI-TIPB peripherals */
|
||||
struct omap_uart_s *uart[3];
|
||||
|
||||
struct omap_gpio_s *gpio;
|
||||
DeviceState *gpio;
|
||||
|
||||
struct omap_mcbsp_s *mcbsp1;
|
||||
struct omap_mcbsp_s *mcbsp3;
|
||||
@ -950,8 +934,6 @@ struct omap_mpu_state_s {
|
||||
struct omap_gpmc_s *gpmc;
|
||||
struct omap_sysctl_s *sysc;
|
||||
|
||||
struct omap_gpif_s *gpif;
|
||||
|
||||
struct omap_mcspi_s *mcspi[2];
|
||||
|
||||
struct omap_dss_s *dss;
|
||||
|
10
hw/omap1.c
10
hw/omap1.c
@ -27,6 +27,7 @@
|
||||
#include "pc.h"
|
||||
#include "blockdev.h"
|
||||
#include "range.h"
|
||||
#include "sysbus.h"
|
||||
|
||||
/* Should signal the TCMI/GPMC */
|
||||
uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
|
||||
@ -3585,7 +3586,6 @@ static void omap1_mpu_reset(void *opaque)
|
||||
omap_uart_reset(mpu->uart[2]);
|
||||
omap_mmc_reset(mpu->mmc);
|
||||
omap_mpuio_reset(mpu->mpuio);
|
||||
omap_gpio_reset(mpu->gpio);
|
||||
omap_uwire_reset(mpu->microwire);
|
||||
omap_pwl_reset(mpu);
|
||||
omap_pwt_reset(mpu);
|
||||
@ -3845,8 +3845,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
|
||||
s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
|
||||
s->wakeup, omap_findclk(s, "clk32-kHz"));
|
||||
|
||||
s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
|
||||
omap_findclk(s, "arm_gpio_ck"));
|
||||
s->gpio = qdev_create(NULL, "omap-gpio");
|
||||
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
|
||||
qdev_init_nofail(s->gpio);
|
||||
sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
|
||||
s->irq[0][OMAP_INT_GPIO_BANK1]);
|
||||
sysbus_mmio_map(sysbus_from_qdev(s->gpio), 0, 0xfffce000);
|
||||
|
||||
s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
|
||||
s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
|
||||
|
34
hw/omap2.c
34
hw/omap2.c
@ -27,6 +27,7 @@
|
||||
#include "qemu-char.h"
|
||||
#include "flash.h"
|
||||
#include "soc_dma.h"
|
||||
#include "sysbus.h"
|
||||
#include "audio/audio.h"
|
||||
|
||||
/* Enhanced Audio Controller (CODEC only) */
|
||||
@ -2203,7 +2204,6 @@ static void omap2_mpu_reset(void *opaque)
|
||||
omap_uart_reset(mpu->uart[1]);
|
||||
omap_uart_reset(mpu->uart[2]);
|
||||
omap_mmc_reset(mpu->mmc);
|
||||
omap_gpif_reset(mpu->gpif);
|
||||
omap_mcspi_reset(mpu->mcspi[0]);
|
||||
omap_mcspi_reset(mpu->mcspi[1]);
|
||||
omap_i2c_reset(mpu->i2c[0]);
|
||||
@ -2232,9 +2232,10 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
|
||||
ram_addr_t sram_base, q2_base;
|
||||
qemu_irq *cpu_irq;
|
||||
qemu_irq dma_irqs[4];
|
||||
omap_clk gpio_clks[4];
|
||||
DriveInfo *dinfo;
|
||||
int i;
|
||||
SysBusDevice *busdev;
|
||||
struct omap_target_agent_s *ta;
|
||||
|
||||
/* Core */
|
||||
s->mpu_model = omap2420;
|
||||
@ -2377,13 +2378,28 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
|
||||
omap_findclk(s, "i2c2.fclk"),
|
||||
omap_findclk(s, "i2c2.iclk"));
|
||||
|
||||
gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
|
||||
gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
|
||||
gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
|
||||
gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
|
||||
s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
|
||||
&s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
|
||||
gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
|
||||
s->gpio = qdev_create(NULL, "omap2-gpio");
|
||||
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
|
||||
qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
|
||||
qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
|
||||
qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
|
||||
qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
|
||||
qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
|
||||
if (s->mpu_model == omap2430) {
|
||||
qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
|
||||
}
|
||||
qdev_init_nofail(s->gpio);
|
||||
busdev = sysbus_from_qdev(s->gpio);
|
||||
sysbus_connect_irq(busdev, 0, s->irq[0][OMAP_INT_24XX_GPIO_BANK1]);
|
||||
sysbus_connect_irq(busdev, 3, s->irq[0][OMAP_INT_24XX_GPIO_BANK2]);
|
||||
sysbus_connect_irq(busdev, 6, s->irq[0][OMAP_INT_24XX_GPIO_BANK3]);
|
||||
sysbus_connect_irq(busdev, 9, s->irq[0][OMAP_INT_24XX_GPIO_BANK4]);
|
||||
ta = omap_l4ta(s->l4, 3);
|
||||
sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1));
|
||||
sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0));
|
||||
sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2));
|
||||
sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4));
|
||||
sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
|
||||
|
||||
s->sdrc = omap_sdrc_init(0x68009000);
|
||||
s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
|
||||
|
260
hw/omap_gpio.c
260
hw/omap_gpio.c
@ -20,10 +20,10 @@
|
||||
|
||||
#include "hw.h"
|
||||
#include "omap.h"
|
||||
/* General-Purpose I/O */
|
||||
#include "sysbus.h"
|
||||
|
||||
struct omap_gpio_s {
|
||||
qemu_irq irq;
|
||||
qemu_irq *in;
|
||||
qemu_irq handler[16];
|
||||
|
||||
uint16_t inputs;
|
||||
@ -35,9 +35,17 @@ struct omap_gpio_s {
|
||||
uint16_t pins;
|
||||
};
|
||||
|
||||
struct omap_gpif_s {
|
||||
SysBusDevice busdev;
|
||||
int mpu_model;
|
||||
void *clk;
|
||||
struct omap_gpio_s omap1;
|
||||
};
|
||||
|
||||
/* General-Purpose I/O of OMAP1 */
|
||||
static void omap_gpio_set(void *opaque, int line, int level)
|
||||
{
|
||||
struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
|
||||
struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1;
|
||||
uint16_t prev = s->inputs;
|
||||
|
||||
if (level)
|
||||
@ -160,7 +168,7 @@ static CPUWriteMemoryFunc * const omap_gpio_writefn[] = {
|
||||
omap_badwidth_write16,
|
||||
};
|
||||
|
||||
void omap_gpio_reset(struct omap_gpio_s *s)
|
||||
static void omap_gpio_reset(struct omap_gpio_s *s)
|
||||
{
|
||||
s->inputs = 0;
|
||||
s->outputs = ~0;
|
||||
@ -171,43 +179,12 @@ void omap_gpio_reset(struct omap_gpio_s *s)
|
||||
s->pins = ~0;
|
||||
}
|
||||
|
||||
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
|
||||
qemu_irq irq, omap_clk clk)
|
||||
{
|
||||
int iomemtype;
|
||||
struct omap_gpio_s *s = (struct omap_gpio_s *)
|
||||
qemu_mallocz(sizeof(struct omap_gpio_s));
|
||||
|
||||
s->irq = irq;
|
||||
s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
|
||||
omap_gpio_reset(s);
|
||||
|
||||
iomemtype = cpu_register_io_memory(omap_gpio_readfn,
|
||||
omap_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
|
||||
cpu_register_physical_memory(base, 0x1000, iomemtype);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
|
||||
{
|
||||
return s->in;
|
||||
}
|
||||
|
||||
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
|
||||
{
|
||||
if (line >= 16 || line < 0)
|
||||
hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
|
||||
s->handler[line] = handler;
|
||||
}
|
||||
|
||||
/* General-Purpose Interface of OMAP2 */
|
||||
struct omap2_gpio_s {
|
||||
qemu_irq irq[2];
|
||||
qemu_irq wkup;
|
||||
qemu_irq *in;
|
||||
qemu_irq handler[32];
|
||||
qemu_irq *handler;
|
||||
|
||||
uint8_t revision;
|
||||
uint8_t config[2];
|
||||
uint32_t inputs;
|
||||
uint32_t outputs;
|
||||
@ -221,8 +198,21 @@ struct omap2_gpio_s {
|
||||
uint8_t delay;
|
||||
};
|
||||
|
||||
struct omap2_gpif_s {
|
||||
SysBusDevice busdev;
|
||||
int mpu_model;
|
||||
void *iclk;
|
||||
void *fclk[6];
|
||||
int modulecount;
|
||||
struct omap2_gpio_s *modules;
|
||||
qemu_irq *handler;
|
||||
int autoidle;
|
||||
int gpo;
|
||||
};
|
||||
|
||||
/* General-Purpose Interface of OMAP2/3 */
|
||||
static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
|
||||
int line)
|
||||
int line)
|
||||
{
|
||||
qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
|
||||
}
|
||||
@ -269,10 +259,12 @@ static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
|
||||
omap2_gpio_module_wake(s, line);
|
||||
}
|
||||
|
||||
static void omap2_gpio_module_set(void *opaque, int line, int level)
|
||||
static void omap2_gpio_set(void *opaque, int line, int level)
|
||||
{
|
||||
struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
|
||||
struct omap2_gpif_s *p = opaque;
|
||||
struct omap2_gpio_s *s = &p->modules[line >> 5];
|
||||
|
||||
line &= 31;
|
||||
if (level) {
|
||||
if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
|
||||
omap2_gpio_module_int(s, line);
|
||||
@ -308,7 +300,7 @@ static uint32_t omap2_gpio_module_read(void *opaque, target_phys_addr_t addr)
|
||||
|
||||
switch (addr) {
|
||||
case 0x00: /* GPIO_REVISION */
|
||||
return 0x18;
|
||||
return s->revision;
|
||||
|
||||
case 0x10: /* GPIO_SYSCONFIG */
|
||||
return s->config[0];
|
||||
@ -583,45 +575,28 @@ static CPUWriteMemoryFunc * const omap2_gpio_module_writefn[] = {
|
||||
omap2_gpio_module_write,
|
||||
};
|
||||
|
||||
static void omap2_gpio_module_init(struct omap2_gpio_s *s,
|
||||
struct omap_target_agent_s *ta, int region,
|
||||
qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
|
||||
omap_clk fclk, omap_clk iclk)
|
||||
static void omap_gpif_reset(DeviceState *dev)
|
||||
{
|
||||
int iomemtype;
|
||||
|
||||
s->irq[0] = mpu;
|
||||
s->irq[1] = dsp;
|
||||
s->wkup = wkup;
|
||||
s->in = qemu_allocate_irqs(omap2_gpio_module_set, s, 32);
|
||||
|
||||
iomemtype = l4_register_io_memory(omap2_gpio_module_readfn,
|
||||
omap2_gpio_module_writefn, s);
|
||||
omap_l4_attach(ta, region, iomemtype);
|
||||
struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s,
|
||||
sysbus_from_qdev(dev));
|
||||
omap_gpio_reset(&s->omap1);
|
||||
}
|
||||
|
||||
struct omap_gpif_s {
|
||||
struct omap2_gpio_s module[5];
|
||||
int modules;
|
||||
|
||||
int autoidle;
|
||||
int gpo;
|
||||
};
|
||||
|
||||
void omap_gpif_reset(struct omap_gpif_s *s)
|
||||
static void omap2_gpif_reset(DeviceState *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->modules; i ++)
|
||||
omap2_gpio_module_reset(s->module + i);
|
||||
|
||||
struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s,
|
||||
sysbus_from_qdev(dev));
|
||||
for (i = 0; i < s->modulecount; i++) {
|
||||
omap2_gpio_module_reset(&s->modules[i]);
|
||||
}
|
||||
s->autoidle = 0;
|
||||
s->gpo = 0;
|
||||
}
|
||||
|
||||
static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
|
||||
static uint32_t omap2_gpif_top_read(void *opaque, target_phys_addr_t addr)
|
||||
{
|
||||
struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
|
||||
struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00: /* IPGENERICOCPSPL_REVISION */
|
||||
@ -647,10 +622,10 @@ static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
|
||||
static void omap2_gpif_top_write(void *opaque, target_phys_addr_t addr,
|
||||
uint32_t value)
|
||||
{
|
||||
struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
|
||||
struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00: /* IPGENERICOCPSPL_REVISION */
|
||||
@ -662,7 +637,7 @@ static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
|
||||
|
||||
case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
|
||||
if (value & (1 << 1)) /* SOFTRESET */
|
||||
omap_gpif_reset(s);
|
||||
omap2_gpif_reset(&s->busdev.qdev);
|
||||
s->autoidle = value & 1;
|
||||
break;
|
||||
|
||||
@ -676,50 +651,119 @@ static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
|
||||
}
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
|
||||
omap_gpif_top_read,
|
||||
omap_gpif_top_read,
|
||||
omap_gpif_top_read,
|
||||
static CPUReadMemoryFunc * const omap2_gpif_top_readfn[] = {
|
||||
omap2_gpif_top_read,
|
||||
omap2_gpif_top_read,
|
||||
omap2_gpif_top_read,
|
||||
};
|
||||
|
||||
static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
|
||||
omap_gpif_top_write,
|
||||
omap_gpif_top_write,
|
||||
omap_gpif_top_write,
|
||||
static CPUWriteMemoryFunc * const omap2_gpif_top_writefn[] = {
|
||||
omap2_gpif_top_write,
|
||||
omap2_gpif_top_write,
|
||||
omap2_gpif_top_write,
|
||||
};
|
||||
|
||||
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
|
||||
qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
|
||||
static int omap_gpio_init(SysBusDevice *dev)
|
||||
{
|
||||
int iomemtype, i;
|
||||
struct omap_gpif_s *s = (struct omap_gpif_s *)
|
||||
qemu_mallocz(sizeof(struct omap_gpif_s));
|
||||
int region[4] = { 0, 2, 4, 5 };
|
||||
|
||||
s->modules = modules;
|
||||
for (i = 0; i < modules; i ++)
|
||||
omap2_gpio_module_init(s->module + i, ta, region[i],
|
||||
irq[i], NULL, NULL, fclk[i], iclk);
|
||||
|
||||
omap_gpif_reset(s);
|
||||
|
||||
iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
|
||||
omap_gpif_top_writefn, s);
|
||||
omap_l4_attach(ta, 1, iomemtype);
|
||||
|
||||
return s;
|
||||
struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, dev);
|
||||
if (!s->clk) {
|
||||
hw_error("omap-gpio: clk not connected\n");
|
||||
}
|
||||
qdev_init_gpio_in(&dev->qdev, omap_gpio_set, 16);
|
||||
qdev_init_gpio_out(&dev->qdev, s->omap1.handler, 16);
|
||||
sysbus_init_irq(dev, &s->omap1.irq);
|
||||
sysbus_init_mmio(dev, 0x1000,
|
||||
cpu_register_io_memory(omap_gpio_readfn,
|
||||
omap_gpio_writefn,
|
||||
&s->omap1,
|
||||
DEVICE_NATIVE_ENDIAN));
|
||||
return 0;
|
||||
}
|
||||
|
||||
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
|
||||
static int omap2_gpio_init(SysBusDevice *dev)
|
||||
{
|
||||
if (start >= s->modules * 32 || start < 0)
|
||||
hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
|
||||
return s->module[start >> 5].in + (start & 31);
|
||||
int i;
|
||||
struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, dev);
|
||||
if (!s->iclk) {
|
||||
hw_error("omap2-gpio: iclk not connected\n");
|
||||
}
|
||||
if (s->mpu_model < omap3430) {
|
||||
s->modulecount = (s->mpu_model < omap2430) ? 4 : 5;
|
||||
sysbus_init_mmio(dev, 0x1000,
|
||||
cpu_register_io_memory(omap2_gpif_top_readfn,
|
||||
omap2_gpif_top_writefn, s,
|
||||
DEVICE_NATIVE_ENDIAN));
|
||||
} else {
|
||||
s->modulecount = 6;
|
||||
}
|
||||
s->modules = qemu_mallocz(s->modulecount * sizeof(struct omap2_gpio_s));
|
||||
s->handler = qemu_mallocz(s->modulecount * 32 * sizeof(qemu_irq));
|
||||
qdev_init_gpio_in(&dev->qdev, omap2_gpio_set, s->modulecount * 32);
|
||||
qdev_init_gpio_out(&dev->qdev, s->handler, s->modulecount * 32);
|
||||
for (i = 0; i < s->modulecount; i++) {
|
||||
struct omap2_gpio_s *m = &s->modules[i];
|
||||
if (!s->fclk[i]) {
|
||||
hw_error("omap2-gpio: fclk%d not connected\n", i);
|
||||
}
|
||||
m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25;
|
||||
m->handler = &s->handler[i * 32];
|
||||
sysbus_init_irq(dev, &m->irq[0]); /* mpu irq */
|
||||
sysbus_init_irq(dev, &m->irq[1]); /* dsp irq */
|
||||
sysbus_init_irq(dev, &m->wkup);
|
||||
sysbus_init_mmio(dev, 0x1000,
|
||||
cpu_register_io_memory(omap2_gpio_module_readfn,
|
||||
omap2_gpio_module_writefn,
|
||||
m, DEVICE_NATIVE_ENDIAN));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
|
||||
/* Using qdev pointer properties for the clocks is not ideal.
|
||||
* qdev should support a generic means of defining a 'port' with
|
||||
* an arbitrary interface for connecting two devices. Then we
|
||||
* could reframe the omap clock API in terms of clock ports,
|
||||
* and get some type safety. For now the best qdev provides is
|
||||
* passing an arbitrary pointer.
|
||||
* (It's not possible to pass in the string which is the clock
|
||||
* name, because this device does not have the necessary information
|
||||
* (ie the struct omap_mpu_state_s*) to do the clockname to pointer
|
||||
* translation.)
|
||||
*/
|
||||
|
||||
static SysBusDeviceInfo omap_gpio_info = {
|
||||
.init = omap_gpio_init,
|
||||
.qdev.name = "omap-gpio",
|
||||
.qdev.size = sizeof(struct omap_gpif_s),
|
||||
.qdev.reset = omap_gpif_reset,
|
||||
.qdev.props = (Property[]) {
|
||||
DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
|
||||
DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static SysBusDeviceInfo omap2_gpio_info = {
|
||||
.init = omap2_gpio_init,
|
||||
.qdev.name = "omap2-gpio",
|
||||
.qdev.size = sizeof(struct omap2_gpif_s),
|
||||
.qdev.reset = omap2_gpif_reset,
|
||||
.qdev.props = (Property[]) {
|
||||
DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
|
||||
DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
|
||||
DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
|
||||
DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
|
||||
DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
|
||||
DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
|
||||
DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
|
||||
DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void omap_gpio_register_device(void)
|
||||
{
|
||||
if (line >= s->modules * 32 || line < 0)
|
||||
hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
|
||||
s->module[line >> 5].handler[line & 31] = handler;
|
||||
sysbus_register_withprop(&omap_gpio_info);
|
||||
sysbus_register_withprop(&omap2_gpio_info);
|
||||
}
|
||||
|
||||
device_init(omap_gpio_register_device)
|
||||
|
26
hw/palm.c
26
hw/palm.c
@ -94,7 +94,7 @@ static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
|
||||
{
|
||||
uWireSlave *tsc;
|
||||
|
||||
tsc = tsc2102_init(omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO]);
|
||||
tsc = tsc2102_init(qdev_get_gpio_in(cpu->gpio, PALMTE_PINTDAV_GPIO));
|
||||
|
||||
omap_uwire_attach(cpu->microwire, tsc, 0);
|
||||
omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
|
||||
@ -163,24 +163,24 @@ static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
|
||||
qemu_irq *misc_gpio;
|
||||
|
||||
omap_mmc_handlers(cpu->mmc,
|
||||
omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO],
|
||||
qdev_get_gpio_in(cpu->gpio, PALMTE_MMC_WP_GPIO),
|
||||
qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
|
||||
[PALMTE_MMC_SWITCH_GPIO]));
|
||||
|
||||
misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
|
||||
omap_gpio_out_set(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]);
|
||||
omap_gpio_out_set(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]);
|
||||
omap_gpio_out_set(cpu->gpio, 11, misc_gpio[2]);
|
||||
omap_gpio_out_set(cpu->gpio, 12, misc_gpio[3]);
|
||||
omap_gpio_out_set(cpu->gpio, 13, misc_gpio[4]);
|
||||
omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]);
|
||||
omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]);
|
||||
qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]);
|
||||
qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]);
|
||||
qdev_connect_gpio_out(cpu->gpio, 11, misc_gpio[2]);
|
||||
qdev_connect_gpio_out(cpu->gpio, 12, misc_gpio[3]);
|
||||
qdev_connect_gpio_out(cpu->gpio, 13, misc_gpio[4]);
|
||||
omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]);
|
||||
omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]);
|
||||
|
||||
/* Reset some inputs to initial state. */
|
||||
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USBDETECT_GPIO]);
|
||||
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USB_OR_DC_GPIO]);
|
||||
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[4]);
|
||||
qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_HEADPHONES_GPIO]);
|
||||
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USBDETECT_GPIO));
|
||||
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USB_OR_DC_GPIO));
|
||||
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, 4));
|
||||
qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_HEADPHONES_GPIO));
|
||||
qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
|
||||
qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
|
||||
qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);
|
||||
|
Loading…
Reference in New Issue
Block a user