Commit 3e508732 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'pmaydell/arm-devs.for-upstream' into staging



# By Peter Crosthwaite (3) and others
# Via Peter Maydell
* pmaydell/arm-devs.for-upstream:
  nand: Don't inherit from Sysbus
  block/nand: Convert Sysbus::init to Device::realize
  block/nand: QOM casting sweep
  i.MX31: Fix PRCS bit test
  arm/boot: Free dtb blob memory after use
  i.MX: Rework functions/types name and use new style initialization
  i.MX: Implement a more complete version of the GPT timer.
  ARM: Allow dumping of device tree

Message-id: 1372184516-32397-1-git-send-email-peter.maydell@linaro.org
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents 8c260b11 7426aa72
......@@ -237,14 +237,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
if (!filename) {
fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
return -1;
goto fail;
}
fdt = load_device_tree(filename, &size);
if (!fdt) {
fprintf(stderr, "Couldn't open dtb file %s\n", filename);
g_free(filename);
return -1;
goto fail;
}
g_free(filename);
......@@ -252,7 +252,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
if (acells == 0 || scells == 0) {
fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
return -1;
goto fail;
}
mem_reg_propsize = acells + scells;
......@@ -264,7 +264,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
} else if (hival != 0) {
fprintf(stderr, "qemu: dtb file not compatible with "
"RAM start address > 4GB\n");
exit(1);
goto fail;
}
mem_reg_property[acells + scells - 1] = cpu_to_be32(binfo->ram_size);
hival = cpu_to_be32(binfo->ram_size >> 32);
......@@ -273,13 +273,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
} else if (hival != 0) {
fprintf(stderr, "qemu: dtb file not compatible with "
"RAM size > 4GB\n");
exit(1);
goto fail;
}
rc = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
mem_reg_propsize * sizeof(uint32_t));
if (rc < 0) {
fprintf(stderr, "couldn't set /memory/reg\n");
goto fail;
}
if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
......@@ -287,6 +288,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
binfo->kernel_cmdline);
if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/bootargs\n");
goto fail;
}
}
......@@ -295,18 +297,27 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
binfo->initrd_start);
if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
goto fail;
}
rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
binfo->initrd_start + binfo->initrd_size);
if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
goto fail;
}
}
qemu_devtree_dumpdtb(fdt, size);
cpu_physical_memory_write(addr, fdt, size);
g_free(fdt);
return 0;
fail:
g_free(fdt);
return -1;
}
static void do_cpu_reset(void *opaque)
......
......@@ -21,7 +21,7 @@
# include "hw/hw.h"
# include "hw/block/flash.h"
# include "sysemu/blockdev.h"
# include "hw/sysbus.h"
#include "hw/qdev.h"
#include "qemu/error-report.h"
# define NAND_CMD_READ0 0x00
......@@ -54,7 +54,8 @@
typedef struct NANDFlashState NANDFlashState;
struct NANDFlashState {
SysBusDevice busdev;
DeviceState parent_obj;
uint8_t manf_id, chip_id;
uint8_t buswidth; /* in BYTES */
int size, pages;
......@@ -82,6 +83,11 @@ struct NANDFlashState {
uint32_t ioaddr_vmstate;
};
#define TYPE_NAND "nand"
#define NAND(obj) \
OBJECT_CHECK(NANDFlashState, (obj), TYPE_NAND)
static void mem_and(uint8_t *dest, const uint8_t *src, size_t n)
{
/* Like memcpy() but we logical-AND the data into the destination */
......@@ -224,7 +230,7 @@ static const struct {
static void nand_reset(DeviceState *dev)
{
NANDFlashState *s = FROM_SYSBUS(NANDFlashState, SYS_BUS_DEVICE(dev));
NANDFlashState *s = NAND(dev);
s->cmd = NAND_CMD_READ0;
s->addr = 0;
s->addrlen = 0;
......@@ -279,7 +285,7 @@ static void nand_command(NANDFlashState *s)
break;
case NAND_CMD_RESET:
nand_reset(&s->busdev.qdev);
nand_reset(DEVICE(s));
break;
case NAND_CMD_PAGEPROGRAM1:
......@@ -319,14 +325,14 @@ static void nand_command(NANDFlashState *s)
static void nand_pre_save(void *opaque)
{
NANDFlashState *s = opaque;
NANDFlashState *s = NAND(opaque);
s->ioaddr_vmstate = s->ioaddr - s->io;
}
static int nand_post_load(void *opaque, int version_id)
{
NANDFlashState *s = opaque;
NANDFlashState *s = NAND(opaque);
if (s->ioaddr_vmstate > sizeof(s->io)) {
return -EINVAL;
......@@ -362,10 +368,10 @@ static const VMStateDescription vmstate_nand = {
}
};
static int nand_device_init(SysBusDevice *dev)
static void nand_realize(DeviceState *dev, Error **errp)
{
int pagesize;
NANDFlashState *s = FROM_SYSBUS(NANDFlashState, dev);
NANDFlashState *s = NAND(dev);
s->buswidth = nand_flash_ids[s->chip_id].width >> 3;
s->size = nand_flash_ids[s->chip_id].size << 20;
......@@ -388,16 +394,17 @@ static int nand_device_init(SysBusDevice *dev)
nand_init_2048(s);
break;
default:
error_report("Unsupported NAND block size");
return -1;
error_setg(errp, "Unsupported NAND block size %#x\n",
1 << s->page_shift);
return;
}
pagesize = 1 << s->oob_shift;
s->mem_oob = 1;
if (s->bdrv) {
if (bdrv_is_read_only(s->bdrv)) {
error_report("Can't use a read-only drive");
return -1;
error_setg(errp, "Can't use a read-only drive");
return;
}
if (bdrv_getlength(s->bdrv) >=
(s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
......@@ -413,8 +420,6 @@ static int nand_device_init(SysBusDevice *dev)
}
/* Give s->ioaddr a sane value in case we save state before it is used. */
s->ioaddr = s->io;
return 0;
}
static Property nand_properties[] = {
......@@ -427,17 +432,16 @@ static Property nand_properties[] = {
static void nand_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = nand_device_init;
dc->realize = nand_realize;
dc->reset = nand_reset;
dc->vmsd = &vmstate_nand;
dc->props = nand_properties;
}
static const TypeInfo nand_info = {
.name = "nand",
.parent = TYPE_SYS_BUS_DEVICE,
.name = TYPE_NAND,
.parent = TYPE_DEVICE,
.instance_size = sizeof(NANDFlashState),
.class_init = nand_class_init,
};
......@@ -456,7 +460,8 @@ static void nand_register_types(void)
void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,
uint8_t ce, uint8_t wp, uint8_t gnd)
{
NANDFlashState *s = (NANDFlashState *) dev;
NANDFlashState *s = NAND(dev);
s->cle = cle;
s->ale = ale;
s->ce = ce;
......@@ -477,7 +482,8 @@ void nand_getpins(DeviceState *dev, int *rb)
void nand_setio(DeviceState *dev, uint32_t value)
{
int i;
NANDFlashState *s = (NANDFlashState *) dev;
NANDFlashState *s = NAND(dev);
if (!s->ce && s->cle) {
if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2)
......@@ -581,7 +587,7 @@ uint32_t nand_getio(DeviceState *dev)
{
int offset;
uint32_t x = 0;
NANDFlashState *s = (NANDFlashState *) dev;
NANDFlashState *s = NAND(dev);
/* Allow sequential reading */
if (!s->iolen && s->cmd == NAND_CMD_READ0) {
......
......@@ -153,7 +153,7 @@ static void update_clocks(IMXCCMState *s)
* approach
*/
if ((s->ccmr & CCMR_PRCS) == 1) {
if ((s->ccmr & CCMR_PRCS) == 2) {
s->pll_refclk_freq = CKIL_FREQ * 1024;
} else {
s->pll_refclk_freq = CKIH_FREQ;
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment