ahci: Add allwinner AHCI
Add a Sysbus AHCI subclass for the Allwinner AHCI. It has a few extra vendor specific registers which are used for phy and power init. Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> Reviewed-by: John Snow <jsnow@redhat.com> Message-id: 833b5b05ed5ade38bf69656679b0a7575e79492b.1445917756.git.crosthwaite.peter@gmail.com [resolved patch context on pull --js] Signed-off-by: John Snow <jsnow@redhat.com>
This commit is contained in:
parent
0487eea48e
commit
377e214539
@ -1690,9 +1690,104 @@ static const TypeInfo sysbus_ahci_info = {
|
||||
.class_init = sysbus_ahci_class_init,
|
||||
};
|
||||
|
||||
#define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
#define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
|
||||
|
||||
static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
AllwinnerAHCIState *a = opaque;
|
||||
uint64_t val = a->regs[addr/4];
|
||||
|
||||
switch (addr / 4) {
|
||||
case ALLWINNER_AHCI_PHYCS0R:
|
||||
val |= 0x2 << 28;
|
||||
break;
|
||||
case ALLWINNER_AHCI_PHYCS2R:
|
||||
val &= ~(0x1 << 24);
|
||||
break;
|
||||
}
|
||||
DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
|
||||
addr, val, size);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
AllwinnerAHCIState *a = opaque;
|
||||
|
||||
DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
|
||||
addr, val, size);
|
||||
a->regs[addr/4] = val;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps allwinner_ahci_mem_ops = {
|
||||
.read = allwinner_ahci_mem_read,
|
||||
.write = allwinner_ahci_mem_write,
|
||||
.valid.min_access_size = 4,
|
||||
.valid.max_access_size = 4,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void allwinner_ahci_init(Object *obj)
|
||||
{
|
||||
SysbusAHCIState *s = SYSBUS_AHCI(obj);
|
||||
AllwinnerAHCIState *a = ALLWINNER_AHCI(obj);
|
||||
|
||||
memory_region_init_io(&a->mmio, OBJECT(obj), &allwinner_ahci_mem_ops, a,
|
||||
"allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE);
|
||||
memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF,
|
||||
&a->mmio);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_allwinner_ahci = {
|
||||
.name = "allwinner-ahci",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, AllwinnerAHCIState,
|
||||
ALLWINNER_AHCI_MMIO_SIZE/4),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void allwinner_ahci_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->vmsd = &vmstate_allwinner_ahci;
|
||||
}
|
||||
|
||||
static const TypeInfo allwinner_ahci_info = {
|
||||
.name = TYPE_ALLWINNER_AHCI,
|
||||
.parent = TYPE_SYSBUS_AHCI,
|
||||
.instance_size = sizeof(AllwinnerAHCIState),
|
||||
.instance_init = allwinner_ahci_init,
|
||||
.class_init = allwinner_ahci_class_init,
|
||||
};
|
||||
|
||||
static void sysbus_ahci_register_types(void)
|
||||
{
|
||||
type_register_static(&sysbus_ahci_info);
|
||||
type_register_static(&allwinner_ahci_info);
|
||||
}
|
||||
|
||||
type_init(sysbus_ahci_register_types)
|
||||
|
@ -386,4 +386,20 @@ typedef struct SysbusAHCIState {
|
||||
uint32_t num_ports;
|
||||
} SysbusAHCIState;
|
||||
|
||||
#define TYPE_ALLWINNER_AHCI "allwinner-ahci"
|
||||
#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
|
||||
TYPE_ALLWINNER_AHCI)
|
||||
|
||||
#define ALLWINNER_AHCI_MMIO_OFF 0x80
|
||||
#define ALLWINNER_AHCI_MMIO_SIZE 0x80
|
||||
|
||||
struct AllwinnerAHCIState {
|
||||
/*< private >*/
|
||||
SysbusAHCIState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
MemoryRegion mmio;
|
||||
uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE/4];
|
||||
};
|
||||
|
||||
#endif /* HW_IDE_AHCI_H */
|
||||
|
@ -9,6 +9,7 @@ struct Monitor;
|
||||
typedef struct AdapterInfo AdapterInfo;
|
||||
typedef struct AddressSpace AddressSpace;
|
||||
typedef struct AioContext AioContext;
|
||||
typedef struct AllwinnerAHCIState AllwinnerAHCIState;
|
||||
typedef struct AudioState AudioState;
|
||||
typedef struct BlockBackend BlockBackend;
|
||||
typedef struct BlockBackendRootState BlockBackendRootState;
|
||||
|
Loading…
Reference in New Issue
Block a user