From nobody Sat May 4 03:38:57 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487612341726572.1377019586178; Mon, 20 Feb 2017 09:39:01 -0800 (PST) Received: from localhost ([::1]:40138 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cfrvQ-0007Ja-9B for importer@patchew.org; Mon, 20 Feb 2017 12:39:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cfrrR-0004OY-Gb for qemu-devel@nongnu.org; Mon, 20 Feb 2017 12:34:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cfrrP-0007G7-LA for qemu-devel@nongnu.org; Mon, 20 Feb 2017 12:34:53 -0500 Received: from bee.antfield.fr ([188.165.75.195]:46340) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cfrrK-0007Ec-4n; Mon, 20 Feb 2017 12:34:46 -0500 From: Clement Deschamps DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=antfield.fr; s=mail; t=1487612085; bh=3jjdw0EealLUhQ265HSJgt71AFsLBZIr0YWu8FRwTxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zi1RtZqAy0iw7lGfLpDkaMs+kG6kvjrCIYPddwyyCKJ1XinaNNS1HDmc7+azQOH17 L25pO+nc4EzThaR5AKdc8VKfP0xxQMWtZ0KkDQlW3FoNRLSnmdRUc6qePicpAeJ3uu z1X4tqdOm33A8v9MnQihhf4G+XkjR5eLOanM1lRg= To: qemu-devel@nongnu.org Date: Mon, 20 Feb 2017 18:34:29 +0100 Message-Id: <20170220173430.31630-2-clement.deschamps@antfield.fr> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170220173430.31630-1-clement.deschamps@antfield.fr> References: <20170220173430.31630-1-clement.deschamps@antfield.fr> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.75.195 Subject: [Qemu-devel] [PATCH 1/2] bcm2835_sdhost: add bcm2835 sdhost controller X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, qemu-arm@nongnu.org, Clement Deschamps , andrew.baumann@microsoft.com, gregory.estrade@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Clement Deschamps --- hw/sd/bcm2835_sdhost.c | 429 +++++++++++++++++++++++++++++++++++++= ++++ include/hw/sd/bcm2835_sdhost.h | 48 +++++ 2 files changed, 477 insertions(+) create mode 100644 hw/sd/bcm2835_sdhost.c create mode 100644 include/hw/sd/bcm2835_sdhost.h diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c new file mode 100644 index 0000000000..03c93ddb25 --- /dev/null +++ b/hw/sd/bcm2835_sdhost.c @@ -0,0 +1,429 @@ +/* + * Raspberry Pi (BCM2835) SD Host Controller + * + * Copyright (c) 2017 Antfield SAS + * + * Authors: + * Clement Deschamps + * Luc Michel + * + * This work is licensed under the terms of the GNU GPL, version 2. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "sysemu/blockdev.h" +#include "hw/sd/bcm2835_sdhost.h" + +#define TYPE_BCM2835_SDHOST_BUS "bcm2835-sdhost-bus" +#define BCM2835_SDHOST_BUS(obj) \ + OBJECT_CHECK(SDBus, (obj), TYPE_BCM2835_SDHOST_BUS) + +#define SDCMD 0x00 /* Command to SD card - 16 R/W */ +#define SDARG 0x04 /* Argument to SD card - 32 R/W */ +#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */ +#define SDCDIV 0x0c /* Start value for clock divider - 11 R/W */ +#define SDRSP0 0x10 /* SD card rsp (31:0) - 32 R */ +#define SDRSP1 0x14 /* SD card rsp (63:32) - 32 R */ +#define SDRSP2 0x18 /* SD card rsp (95:64) - 32 R */ +#define SDRSP3 0x1c /* SD card rsp (127:96) - 32 R */ +#define SDHSTS 0x20 /* SD host status - 11 R */ +#define SDVDD 0x30 /* SD card power control - 1 R/W */ +#define SDEDM 0x34 /* Emergency Debug Mode - 13 R/W */ +#define SDHCFG 0x38 /* Host configuration - 2 R/W */ +#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */ +#define SDDATA 0x40 /* Data to/from SD card - 32 R/W */ +#define SDHBLC 0x50 /* Host block count (SDIO/SDHC) - 9 R/W */ + +#define SDCMD_NEW_FLAG 0x8000 +#define SDCMD_FAIL_FLAG 0x4000 +#define SDCMD_BUSYWAIT 0x800 +#define SDCMD_NO_RESPONSE 0x400 +#define SDCMD_LONG_RESPONSE 0x200 +#define SDCMD_WRITE_CMD 0x80 +#define SDCMD_READ_CMD 0x40 +#define SDCMD_CMD_MASK 0x3f + +#define SDCDIV_MAX_CDIV 0x7ff + +#define SDHSTS_BUSY_IRPT 0x400 +#define SDHSTS_BLOCK_IRPT 0x200 +#define SDHSTS_SDIO_IRPT 0x100 +#define SDHSTS_REW_TIME_OUT 0x80 +#define SDHSTS_CMD_TIME_OUT 0x40 +#define SDHSTS_CRC16_ERROR 0x20 +#define SDHSTS_CRC7_ERROR 0x10 +#define SDHSTS_FIFO_ERROR 0x08 +/* Reserved */ +/* Reserved */ +#define SDHSTS_DATA_FLAG 0x01 + +#define SDHCFG_BUSY_IRPT_EN (1 << 10) +#define SDHCFG_BLOCK_IRPT_EN (1 << 8) +#define SDHCFG_SDIO_IRPT_EN (1 << 5) +#define SDHCFG_DATA_IRPT_EN (1 << 4) +#define SDHCFG_SLOW_CARD (1 << 3) +#define SDHCFG_WIDE_EXT_BUS (1 << 2) +#define SDHCFG_WIDE_INT_BUS (1 << 1) +#define SDHCFG_REL_CMD_LINE (1 << 0) + +#define SDEDM_FORCE_DATA_MODE (1 << 19) +#define SDEDM_CLOCK_PULSE (1 << 20) +#define SDEDM_BYPASS (1 << 21) + +#define SDEDM_WRITE_THRESHOLD_SHIFT 9 +#define SDEDM_READ_THRESHOLD_SHIFT 14 +#define SDEDM_THRESHOLD_MASK 0x1f + +#define SDEDM_FSM_MASK 0xf +#define SDEDM_FSM_IDENTMODE 0x0 +#define SDEDM_FSM_DATAMODE 0x1 +#define SDEDM_FSM_READDATA 0x2 +#define SDEDM_FSM_WRITEDATA 0x3 +#define SDEDM_FSM_READWAIT 0x4 +#define SDEDM_FSM_READCRC 0x5 +#define SDEDM_FSM_WRITECRC 0x6 +#define SDEDM_FSM_WRITEWAIT1 0x7 +#define SDEDM_FSM_POWERDOWN 0x8 +#define SDEDM_FSM_POWERUP 0x9 +#define SDEDM_FSM_WRITESTART1 0xa +#define SDEDM_FSM_WRITESTART2 0xb +#define SDEDM_FSM_GENPULSES 0xc +#define SDEDM_FSM_WRITEWAIT2 0xd +#define SDEDM_FSM_STARTPOWDOWN 0xf + +#define SDDATA_FIFO_WORDS 16 + +static void bcm2835_sdhost_update_irq(BCM2835SDHostState *s) +{ + uint32_t irq =3D s->status & + (SDHSTS_BUSY_IRPT | SDHSTS_BLOCK_IRPT | SDHSTS_SDIO_IRPT); + qemu_set_irq(s->irq, !!irq); +} + +static void bcm2835_sdhost_send_command(BCM2835SDHostState *s) +{ + SDRequest request; + uint8_t rsp[16]; + int rlen; + + request.cmd =3D s->cmd & SDCMD_CMD_MASK; + request.arg =3D s->cmdarg; + + rlen =3D sdbus_do_command(&s->sdbus, &request, rsp); + if (rlen < 0) { + goto error; + } + if (!(s->cmd & SDCMD_NO_RESPONSE)) { +#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \ + | (rsp[n + 2] << 8) | rsp[n + 3]) + if (rlen =3D=3D 0 || (rlen =3D=3D 4 && (s->cmd & SDCMD_LONG_RESPON= SE))) { + goto error; + } + if (rlen !=3D 4 && rlen !=3D 16) { + goto error; + } + if (rlen =3D=3D 4) { + s->rsp[0] =3D RWORD(0); + s->rsp[1] =3D s->rsp[2] =3D s->rsp[3] =3D 0; + } else { + s->rsp[0] =3D RWORD(12); + s->rsp[1] =3D RWORD(8); + s->rsp[2] =3D RWORD(4); + s->rsp[3] =3D RWORD(0); + } +#undef RWORD + } + return; + +error: + s->cmd |=3D SDCMD_FAIL_FLAG; + s->status |=3D SDHSTS_CMD_TIME_OUT; +} + +static void bcm2835_sdhost_fifo_push(BCM2835SDHostState *s, uint32_t value) +{ + int n; + + if (s->fifo_len =3D=3D BCM2835_SDHOST_FIFO_LEN) { + /* FIFO overflow */ + return; + } + n =3D (s->fifo_pos + s->fifo_len) & (BCM2835_SDHOST_FIFO_LEN - 1); + s->fifo_len++; + s->fifo[n] =3D value; +} + +static uint32_t bcm2835_sdhost_fifo_pop(BCM2835SDHostState *s) +{ + uint32_t value; + + if (s->fifo_len =3D=3D 0) { + /* FIFO underflow */ + return 0; + } + value =3D s->fifo[s->fifo_pos]; + s->fifo_len--; + s->fifo_pos =3D (s->fifo_pos + 1) & (BCM2835_SDHOST_FIFO_LEN - 1); + return value; +} + +static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) +{ + uint32_t value =3D 0; + int n; + int is_read; + + is_read =3D (s->cmd & SDCMD_READ_CMD) !=3D 0; + if (s->datacnt !=3D 0 && (!is_read || sdbus_data_ready(&s->sdbus))) { + if (is_read) { + n =3D 0; + while (s->datacnt && s->fifo_len < BCM2835_SDHOST_FIFO_LEN) { + value |=3D (uint32_t)sdbus_read_data(&s->sdbus) << (n * 8); + s->datacnt--; + n++; + if (n =3D=3D 4) { + bcm2835_sdhost_fifo_push(s, value); + n =3D 0; + value =3D 0; + } + } + if (n !=3D 0) { + bcm2835_sdhost_fifo_push(s, value); + } + } else { /* write */ + n =3D 0; + while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) { + if (n =3D=3D 0) { + value =3D bcm2835_sdhost_fifo_pop(s); + n =3D 4; + } + n--; + s->datacnt--; + sdbus_write_data(&s->sdbus, value & 0xff); + value >>=3D 8; + } + } + } + if (s->datacnt =3D=3D 0) { + s->status |=3D SDHSTS_DATA_FLAG; + + s->edm &=3D ~0xf; + s->edm |=3D SDEDM_FSM_DATAMODE; + + if (s->config & SDHCFG_DATA_IRPT_EN) { + s->status |=3D SDHSTS_SDIO_IRPT; + } + + if ((s->cmd & SDCMD_BUSYWAIT) && (s->config & SDHCFG_BUSY_IRPT_EN)= ) { + s->status |=3D SDHSTS_BUSY_IRPT; + } + + if ((s->cmd & SDCMD_WRITE_CMD) && (s->config & SDHCFG_BLOCK_IRPT_E= N)) { + s->status |=3D SDHSTS_BLOCK_IRPT; + } + + bcm2835_sdhost_update_irq(s); + } + + s->edm &=3D ~(0x1f << 4); + s->edm |=3D ((s->fifo_len & 0x1f) << 4); +} + +static uint64_t bcm2835_sdhost_read(void *opaque, hwaddr offset, + unsigned size) +{ + BCM2835SDHostState *s =3D (BCM2835SDHostState *)opaque; + uint32_t res =3D 0; + + switch (offset) { + case SDCMD: + res =3D s->cmd; + break; + case SDHSTS: + res =3D s->status; + break; + case SDRSP0: + res =3D s->rsp[0]; + break; + case SDRSP1: + res =3D s->rsp[1]; + break; + case SDRSP2: + res =3D s->rsp[2]; + break; + case SDRSP3: + res =3D s->rsp[3]; + break; + case SDEDM: + res =3D s->edm; + break; + case SDVDD: + res =3D s->vdd; + break; + case SDDATA: + res =3D bcm2835_sdhost_fifo_pop(s); + bcm2835_sdhost_fifo_run(s); + break; + case SDHBCT: + res =3D s->hbct; + break; + case SDHBLC: + res =3D s->hblc; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); + res =3D 0; + break; + } + + return res; +} + +static void bcm2835_sdhost_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + BCM2835SDHostState *s =3D (BCM2835SDHostState *)opaque; + + switch (offset) { + case SDCMD: + s->cmd =3D value; + if (value & SDCMD_NEW_FLAG) { + bcm2835_sdhost_send_command(s); + bcm2835_sdhost_fifo_run(s); + s->cmd &=3D ~SDCMD_NEW_FLAG; + } + break; + case SDTOUT: + break; + case SDCDIV: + break; + case SDHSTS: + s->status &=3D ~value; + bcm2835_sdhost_update_irq(s); + break; + case SDARG: + s->cmdarg =3D value; + break; + case SDEDM: + if ((value & 0xf) =3D=3D 0xf) { + /* power down */ + value &=3D ~0xf; + } + s->edm =3D value; + break; + case SDHCFG: + s->config =3D value; + bcm2835_sdhost_fifo_run(s); + break; + case SDVDD: + s->vdd =3D value; + break; + case SDDATA: + bcm2835_sdhost_fifo_push(s, value); + bcm2835_sdhost_fifo_run(s); + break; + case SDHBCT: + s->hbct =3D value; + break; + case SDHBLC: + s->hblc =3D value; + s->datacnt =3D s->hblc * s->hbct; + bcm2835_sdhost_fifo_run(s); + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); + break; + } +} + +static const MemoryRegionOps bcm2835_sdhost_ops =3D { + .read =3D bcm2835_sdhost_read, + .write =3D bcm2835_sdhost_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static const VMStateDescription vmstate_bcm2835_sdhost =3D { + .name =3D TYPE_BCM2835_SDHOST, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(cmd, BCM2835SDHostState), + VMSTATE_UINT32(cmdarg, BCM2835SDHostState), + VMSTATE_UINT32(status, BCM2835SDHostState), + VMSTATE_UINT32_ARRAY(rsp, BCM2835SDHostState, 4), + VMSTATE_UINT32(config, BCM2835SDHostState), + VMSTATE_UINT32(edm, BCM2835SDHostState), + VMSTATE_UINT32(vdd, BCM2835SDHostState), + VMSTATE_UINT32(hbct, BCM2835SDHostState), + VMSTATE_UINT32(hblc, BCM2835SDHostState), + VMSTATE_INT32(fifo_pos, BCM2835SDHostState), + VMSTATE_INT32(fifo_len, BCM2835SDHostState), + VMSTATE_UINT32_ARRAY(fifo, BCM2835SDHostState, BCM2835_SDHOST_FIFO= _LEN), + VMSTATE_UINT32(datacnt, BCM2835SDHostState), + VMSTATE_END_OF_LIST() + } +}; + +static void bcm2835_sdhost_init(Object *obj) +{ + BCM2835SDHostState *s =3D BCM2835_SDHOST(obj); + + qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), + TYPE_BCM2835_SDHOST_BUS, DEVICE(s), "sd-bus"); + + memory_region_init_io(&s->iomem, obj, &bcm2835_sdhost_ops, s, + TYPE_BCM2835_SDHOST, 0x1000); + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); + sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); +} + +static void bcm2835_sdhost_reset(DeviceState *dev) +{ + BCM2835SDHostState *s =3D BCM2835_SDHOST(dev); + + s->cmd =3D 0; + s->cmdarg =3D 0; + s->edm =3D 0x0000c60f; + s->config =3D 0; + s->hbct =3D 0; + s->hblc =3D 0; + s->datacnt =3D 0; + s->fifo_pos =3D 0; + s->fifo_len =3D 0; +} + +static void bcm2835_sdhost_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->reset =3D bcm2835_sdhost_reset; + dc->vmsd =3D &vmstate_bcm2835_sdhost; +} + +static TypeInfo bcm2835_sdhost_info =3D { + .name =3D TYPE_BCM2835_SDHOST, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(BCM2835SDHostState), + .class_init =3D bcm2835_sdhost_class_init, + .instance_init =3D bcm2835_sdhost_init, +}; + +static const TypeInfo bcm2835_sdhost_bus_info =3D { + .name =3D TYPE_BCM2835_SDHOST_BUS, + .parent =3D TYPE_SD_BUS, + .instance_size =3D sizeof(SDBus), +}; + +static void bcm2835_sdhost_register_types(void) +{ + type_register_static(&bcm2835_sdhost_info); + type_register_static(&bcm2835_sdhost_bus_info); +} + +type_init(bcm2835_sdhost_register_types) diff --git a/include/hw/sd/bcm2835_sdhost.h b/include/hw/sd/bcm2835_sdhost.h new file mode 100644 index 0000000000..d716dbcd83 --- /dev/null +++ b/include/hw/sd/bcm2835_sdhost.h @@ -0,0 +1,48 @@ +/* + * Raspberry Pi (BCM2835) SD Host Controller + * + * Copyright (c) 2017 Antfield SAS + * + * Authors: + * Clement Deschamps + * Luc Michel + * + * This work is licensed under the terms of the GNU GPL, version 2. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_SDHOST_H +#define BCM2835_SDHOST_H + +#include "hw/sysbus.h" +#include "hw/sd/sd.h" + +#define TYPE_BCM2835_SDHOST "bcm2835-sdhost" +#define BCM2835_SDHOST(obj) \ + OBJECT_CHECK(BCM2835SDHostState, (obj), TYPE_BCM2835_SDHOST) + +#define BCM2835_SDHOST_FIFO_LEN 16 + +typedef struct { + SysBusDevice busdev; + SDBus sdbus; + MemoryRegion iomem; + + uint32_t cmd; + uint32_t cmdarg; + uint32_t status; + uint32_t rsp[4]; + uint32_t config; + uint32_t edm; + uint32_t vdd; + uint32_t hbct; + uint32_t hblc; + int32_t fifo_pos; + int32_t fifo_len; + uint32_t fifo[BCM2835_SDHOST_FIFO_LEN]; + uint32_t datacnt; + + qemu_irq irq; +} BCM2835SDHostState; + +#endif --=20 2.11.0 From nobody Sat May 4 03:38:57 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487612182862289.6156111099908; Mon, 20 Feb 2017 09:36:22 -0800 (PST) Received: from localhost ([::1]:40130 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cfrsr-00054v-EZ for importer@patchew.org; Mon, 20 Feb 2017 12:36:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48288) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cfrrQ-0004O6-2V for qemu-devel@nongnu.org; Mon, 20 Feb 2017 12:34:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cfrrO-0007Fq-UK for qemu-devel@nongnu.org; Mon, 20 Feb 2017 12:34:52 -0500 Received: from bee.antfield.fr ([188.165.75.195]:46354) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cfrrL-0007Ev-8j; Mon, 20 Feb 2017 12:34:47 -0500 From: Clement Deschamps DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=antfield.fr; s=mail; t=1487612086; bh=nDUagjgfm0blswDBYlsYUV4nUwjSXhKdcYJxTYb3pi4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yuQ008ZuOB9b+1WhSVsd8/1zldCv29+1qABXLHR4cAxXNZprgM+00UESy8RRSHVTt Resd77j7Wh+UUqXDYjvV6+5ackctyUa5gTJJR3cNrK2aEQaGxXakYXfyzKjF1E4HFg 6BHi9Y/dvfzChM+LMSuMVHYLZk3Uf3Py2B2UPmLY= To: qemu-devel@nongnu.org Date: Mon, 20 Feb 2017 18:34:30 +0100 Message-Id: <20170220173430.31630-3-clement.deschamps@antfield.fr> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170220173430.31630-1-clement.deschamps@antfield.fr> References: <20170220173430.31630-1-clement.deschamps@antfield.fr> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.75.195 Subject: [Qemu-devel] [PATCH 2/2] bcm2835: add bcm2835_sdhost to bcm2835 platform X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, qemu-arm@nongnu.org, Clement Deschamps , andrew.baumann@microsoft.com, gregory.estrade@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Clement Deschamps --- hw/arm/bcm2835_peripherals.c | 24 ++++++++++++++++++++++++ hw/arm/bcm2836.c | 7 +++++++ hw/arm/raspi.c | 13 ++++++++++++- hw/sd/Makefile.objs | 1 + include/hw/arm/bcm2835_peripherals.h | 2 ++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 2e641a3989..9306c8c5f3 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -91,6 +91,11 @@ static void bcm2835_peripherals_init(Object *obj) object_property_add_child(obj, "sdhci", OBJECT(&s->sdhci), NULL); qdev_set_parent_bus(DEVICE(&s->sdhci), sysbus_get_default()); =20 + /* SDHOST */ + object_initialize(&s->sdhost, sizeof(s->sdhost), TYPE_BCM2835_SDHOST); + object_property_add_child(obj, "sdhost", OBJECT(&s->sdhost), NULL); + qdev_set_parent_bus(DEVICE(&s->sdhost), sysbus_get_default()); + /* DMA Channels */ object_initialize(&s->dma, sizeof(s->dma), TYPE_BCM2835_DMA); object_property_add_child(obj, "dma", OBJECT(&s->dma), NULL); @@ -259,6 +264,25 @@ static void bcm2835_peripherals_realize(DeviceState *d= ev, Error **errp) return; } =20 + /* SDHOST */ + object_property_set_bool(OBJECT(&s->sdhost), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + memory_region_add_subregion(&s->peri_mr, MMCI0_OFFSET, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhost), 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhost), 0, + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_SDIO)); + object_property_add_alias(OBJECT(s), "sd-bus-2", OBJECT(&s->sdhost), + "sd-bus", &err); + if (err) { + error_propagate(errp, err); + return; + } + /* DMA Channels */ object_property_set_bool(OBJECT(&s->dma), true, "realized", &err); if (err) { diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c index 8451190a19..e69c49cf1d 100644 --- a/hw/arm/bcm2836.c +++ b/hw/arm/bcm2836.c @@ -85,6 +85,13 @@ static void bcm2836_realize(DeviceState *dev, Error **er= rp) return; } =20 + object_property_add_alias(OBJECT(s), "sd-bus-2", OBJECT(&s->peripheral= s), + "sd-bus-2", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0, BCM2836_PERI_BASE, 1); =20 diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 2b295f14c4..cdb7a2bbac 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -142,7 +142,7 @@ static void raspi2_init(MachineState *machine) object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abo= rt); =20 /* Create and plug in the SD cards */ - di =3D drive_get_next(IF_SD); + di =3D drive_get_by_index(IF_SD, 0); blk =3D di ? blk_by_legacy_dinfo(di) : NULL; bus =3D qdev_get_child_bus(DEVICE(&s->soc), "sd-bus"); if (bus =3D=3D NULL) { @@ -153,6 +153,17 @@ static void raspi2_init(MachineState *machine) qdev_prop_set_drive(carddev, "drive", blk, &error_fatal); object_property_set_bool(OBJECT(carddev), true, "realized", &error_fat= al); =20 + di =3D drive_get_by_index(IF_SD, 1); + blk =3D di ? blk_by_legacy_dinfo(di) : NULL; + bus =3D qdev_get_child_bus(DEVICE(&s->soc), "sd-bus-2"); + if (bus =3D=3D NULL) { + error_report("No secondary SD bus found in SOC object"); + exit(1); + } + carddev =3D qdev_create(bus, TYPE_SD_CARD); + qdev_prop_set_drive(carddev, "drive", blk, &error_fatal); + object_property_set_bool(OBJECT(carddev), true, "realized", &error_fat= al); + vcram_size =3D object_property_get_int(OBJECT(&s->soc), "vcram-size", &error_abort); setup_boot(machine, 2, machine->ram_size - vcram_size); diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs index 31c83308f2..c2b7664264 100644 --- a/hw/sd/Makefile.objs +++ b/hw/sd/Makefile.objs @@ -6,3 +6,4 @@ common-obj-$(CONFIG_SDHCI) +=3D sdhci.o obj-$(CONFIG_MILKYMIST) +=3D milkymist-memcard.o obj-$(CONFIG_OMAP) +=3D omap_mmc.o obj-$(CONFIG_PXA2XX) +=3D pxa2xx_mmci.o +obj-$(CONFIG_RASPI) +=3D bcm2835_sdhost.o diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_= peripherals.h index e12ae3721a..3243038559 100644 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -20,6 +20,7 @@ #include "hw/intc/bcm2835_ic.h" #include "hw/misc/bcm2835_property.h" #include "hw/misc/bcm2835_mbox.h" +#include "hw/sd/bcm2835_sdhost.h" #include "hw/sd/sdhci.h" =20 #define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals" @@ -42,6 +43,7 @@ typedef struct BCM2835PeripheralState { BCM2835ICState ic; BCM2835PropertyState property; BCM2835MboxState mboxes; + BCM2835SDHostState sdhost; SDHCIState sdhci; } BCM2835PeripheralState; =20 --=20 2.11.0