xref: /qemu/include/hw/sd/sd.h (revision c3287c0f)
1e3382ef0SSai Pavan Boddu /*
2e3382ef0SSai Pavan Boddu  * SD Memory Card emulation.  Mostly correct for MMC too.
3e3382ef0SSai Pavan Boddu  *
4e3382ef0SSai Pavan Boddu  * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
5e3382ef0SSai Pavan Boddu  *
6e3382ef0SSai Pavan Boddu  * Redistribution and use in source and binary forms, with or without
7e3382ef0SSai Pavan Boddu  * modification, are permitted provided that the following conditions
8e3382ef0SSai Pavan Boddu  * are met:
9e3382ef0SSai Pavan Boddu  *
10e3382ef0SSai Pavan Boddu  * 1. Redistributions of source code must retain the above copyright
11e3382ef0SSai Pavan Boddu  *    notice, this list of conditions and the following disclaimer.
12e3382ef0SSai Pavan Boddu  * 2. Redistributions in binary form must reproduce the above copyright
13e3382ef0SSai Pavan Boddu  *    notice, this list of conditions and the following disclaimer in
14e3382ef0SSai Pavan Boddu  *    the documentation and/or other materials provided with the
15e3382ef0SSai Pavan Boddu  *    distribution.
16e3382ef0SSai Pavan Boddu  *
17e3382ef0SSai Pavan Boddu  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
18e3382ef0SSai Pavan Boddu  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19e3382ef0SSai Pavan Boddu  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20e3382ef0SSai Pavan Boddu  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR
21e3382ef0SSai Pavan Boddu  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22e3382ef0SSai Pavan Boddu  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23e3382ef0SSai Pavan Boddu  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24e3382ef0SSai Pavan Boddu  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25e3382ef0SSai Pavan Boddu  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26e3382ef0SSai Pavan Boddu  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27e3382ef0SSai Pavan Boddu  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28e3382ef0SSai Pavan Boddu  */
292a6a4076SMarkus Armbruster 
302a6a4076SMarkus Armbruster #ifndef HW_SD_H
312a6a4076SMarkus Armbruster #define HW_SD_H
32e3382ef0SSai Pavan Boddu 
33a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h"
34db1015e9SEduardo Habkost #include "qom/object.h"
3533c11879SPaolo Bonzini 
36e3382ef0SSai Pavan Boddu #define OUT_OF_RANGE            (1 << 31)
37e3382ef0SSai Pavan Boddu #define ADDRESS_ERROR           (1 << 30)
38e3382ef0SSai Pavan Boddu #define BLOCK_LEN_ERROR         (1 << 29)
39e3382ef0SSai Pavan Boddu #define ERASE_SEQ_ERROR         (1 << 28)
40e3382ef0SSai Pavan Boddu #define ERASE_PARAM             (1 << 27)
41e3382ef0SSai Pavan Boddu #define WP_VIOLATION            (1 << 26)
42e3382ef0SSai Pavan Boddu #define CARD_IS_LOCKED          (1 << 25)
43e3382ef0SSai Pavan Boddu #define LOCK_UNLOCK_FAILED      (1 << 24)
44e3382ef0SSai Pavan Boddu #define COM_CRC_ERROR           (1 << 23)
45e3382ef0SSai Pavan Boddu #define ILLEGAL_COMMAND         (1 << 22)
46e3382ef0SSai Pavan Boddu #define CARD_ECC_FAILED         (1 << 21)
47e3382ef0SSai Pavan Boddu #define CC_ERROR                (1 << 20)
48e3382ef0SSai Pavan Boddu #define SD_ERROR                (1 << 19)
49e3382ef0SSai Pavan Boddu #define CID_CSD_OVERWRITE       (1 << 16)
50e3382ef0SSai Pavan Boddu #define WP_ERASE_SKIP           (1 << 15)
51e3382ef0SSai Pavan Boddu #define CARD_ECC_DISABLED       (1 << 14)
52e3382ef0SSai Pavan Boddu #define ERASE_RESET             (1 << 13)
53e3382ef0SSai Pavan Boddu #define CURRENT_STATE           (7 << 9)
54e3382ef0SSai Pavan Boddu #define READY_FOR_DATA          (1 << 8)
55e3382ef0SSai Pavan Boddu #define APP_CMD                 (1 << 5)
56e3382ef0SSai Pavan Boddu #define AKE_SEQ_ERROR           (1 << 3)
57e3382ef0SSai Pavan Boddu 
582f0939c2SPhilippe Mathieu-Daudé enum SDPhySpecificationVersion {
592f0939c2SPhilippe Mathieu-Daudé     SD_PHY_SPECv1_10_VERS     = 1,
602f0939c2SPhilippe Mathieu-Daudé     SD_PHY_SPECv2_00_VERS     = 2,
612c511375SPhilippe Mathieu-Daudé     SD_PHY_SPECv3_01_VERS     = 3,
622f0939c2SPhilippe Mathieu-Daudé };
632f0939c2SPhilippe Mathieu-Daudé 
64e3382ef0SSai Pavan Boddu typedef enum {
650034ebe6SPhilippe Mathieu-Daudé     SD_VOLTAGE_0_4V     = 400,  /* currently not supported */
660034ebe6SPhilippe Mathieu-Daudé     SD_VOLTAGE_1_8V     = 1800,
670034ebe6SPhilippe Mathieu-Daudé     SD_VOLTAGE_3_0V     = 3000,
680034ebe6SPhilippe Mathieu-Daudé     SD_VOLTAGE_3_3V     = 3300,
690034ebe6SPhilippe Mathieu-Daudé } sd_voltage_mv_t;
700034ebe6SPhilippe Mathieu-Daudé 
710034ebe6SPhilippe Mathieu-Daudé typedef enum  {
720034ebe6SPhilippe Mathieu-Daudé     UHS_NOT_SUPPORTED   = 0,
730034ebe6SPhilippe Mathieu-Daudé     UHS_I               = 1,
740034ebe6SPhilippe Mathieu-Daudé     UHS_II              = 2,    /* currently not supported */
750034ebe6SPhilippe Mathieu-Daudé     UHS_III             = 3,    /* currently not supported */
760034ebe6SPhilippe Mathieu-Daudé } sd_uhs_mode_t;
770034ebe6SPhilippe Mathieu-Daudé 
780034ebe6SPhilippe Mathieu-Daudé typedef enum {
79e3382ef0SSai Pavan Boddu     sd_none = -1,
80e3382ef0SSai Pavan Boddu     sd_bc = 0, /* broadcast -- no response */
81e3382ef0SSai Pavan Boddu     sd_bcr,    /* broadcast with response */
82e3382ef0SSai Pavan Boddu     sd_ac,     /* addressed -- no data transfer */
83e3382ef0SSai Pavan Boddu     sd_adtc,   /* addressed with data transfer */
84e3382ef0SSai Pavan Boddu } sd_cmd_type_t;
85e3382ef0SSai Pavan Boddu 
86e3382ef0SSai Pavan Boddu typedef struct {
87e3382ef0SSai Pavan Boddu     uint8_t cmd;
88e3382ef0SSai Pavan Boddu     uint32_t arg;
89e3382ef0SSai Pavan Boddu     uint8_t crc;
90e3382ef0SSai Pavan Boddu } SDRequest;
91e3382ef0SSai Pavan Boddu 
92e3382ef0SSai Pavan Boddu 
93260bc9d8SPeter Maydell #define TYPE_SD_CARD "sd-card"
94a489d195SEduardo Habkost OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
95260bc9d8SPeter Maydell 
96c3287c0fSCédric Le Goater #define TYPE_SD_CARD_SPI "sd-card-spi"
97c3287c0fSCédric Le Goater DECLARE_INSTANCE_CHECKER(SDState, SD_CARD_SPI, TYPE_SD_CARD_SPI)
98c3287c0fSCédric Le Goater 
99db1015e9SEduardo Habkost struct SDCardClass {
100c759a790SPeter Maydell     /*< private >*/
101c759a790SPeter Maydell     DeviceClass parent_class;
102c759a790SPeter Maydell     /*< public >*/
103c759a790SPeter Maydell 
104c759a790SPeter Maydell     int (*do_command)(SDState *sd, SDRequest *req, uint8_t *response);
105c769a88dSPhilippe Mathieu-Daudé     /**
106c769a88dSPhilippe Mathieu-Daudé      * Write a byte to a SD card.
107c769a88dSPhilippe Mathieu-Daudé      * @sd: card
108c769a88dSPhilippe Mathieu-Daudé      * @value: byte to write
109c769a88dSPhilippe Mathieu-Daudé      *
110c769a88dSPhilippe Mathieu-Daudé      * Write a byte on the data lines of a SD card.
111c769a88dSPhilippe Mathieu-Daudé      */
112c769a88dSPhilippe Mathieu-Daudé     void (*write_byte)(SDState *sd, uint8_t value);
113c769a88dSPhilippe Mathieu-Daudé     /**
114c769a88dSPhilippe Mathieu-Daudé      * Read a byte from a SD card.
115c769a88dSPhilippe Mathieu-Daudé      * @sd: card
116c769a88dSPhilippe Mathieu-Daudé      *
117c769a88dSPhilippe Mathieu-Daudé      * Read a byte from the data lines of a SD card.
118c769a88dSPhilippe Mathieu-Daudé      *
119c769a88dSPhilippe Mathieu-Daudé      * Return: byte value read
120c769a88dSPhilippe Mathieu-Daudé      */
121c769a88dSPhilippe Mathieu-Daudé     uint8_t (*read_byte)(SDState *sd);
122995731d3SBin Meng     bool (*receive_ready)(SDState *sd);
123c759a790SPeter Maydell     bool (*data_ready)(SDState *sd);
1240034ebe6SPhilippe Mathieu-Daudé     void (*set_voltage)(SDState *sd, uint16_t millivolts);
125da346922SPhilippe Mathieu-Daudé     uint8_t (*get_dat_lines)(SDState *sd);
126da346922SPhilippe Mathieu-Daudé     bool (*get_cmd_line)(SDState *sd);
127c759a790SPeter Maydell     void (*enable)(SDState *sd, bool enable);
128c759a790SPeter Maydell     bool (*get_inserted)(SDState *sd);
129c759a790SPeter Maydell     bool (*get_readonly)(SDState *sd);
1301b4a2342SPhilippe Mathieu-Daudé 
1311b4a2342SPhilippe Mathieu-Daudé     const struct SDProto *proto;
132db1015e9SEduardo Habkost };
133c759a790SPeter Maydell 
134c759a790SPeter Maydell #define TYPE_SD_BUS "sd-bus"
135c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(SDBus, SDBusClass,
13630b5707cSEduardo Habkost                     SD_BUS)
137c759a790SPeter Maydell 
138c759a790SPeter Maydell struct SDBus {
139c759a790SPeter Maydell     BusState qbus;
140c759a790SPeter Maydell };
141c759a790SPeter Maydell 
142db1015e9SEduardo Habkost struct SDBusClass {
143c759a790SPeter Maydell     /*< private >*/
144c759a790SPeter Maydell     BusClass parent_class;
145c759a790SPeter Maydell     /*< public >*/
146c759a790SPeter Maydell 
147c759a790SPeter Maydell     /* These methods are called by the SD device to notify the controller
148c759a790SPeter Maydell      * when the card insertion or readonly status changes
149c759a790SPeter Maydell      */
150c759a790SPeter Maydell     void (*set_inserted)(DeviceState *dev, bool inserted);
151c759a790SPeter Maydell     void (*set_readonly)(DeviceState *dev, bool readonly);
152db1015e9SEduardo Habkost };
153c759a790SPeter Maydell 
154c759a790SPeter Maydell /* Functions to be used by qdevified callers (working via
155c759a790SPeter Maydell  * an SDBus rather than directly with SDState)
156c759a790SPeter Maydell  */
1570034ebe6SPhilippe Mathieu-Daudé void sdbus_set_voltage(SDBus *sdbus, uint16_t millivolts);
158da346922SPhilippe Mathieu-Daudé uint8_t sdbus_get_dat_lines(SDBus *sdbus);
159da346922SPhilippe Mathieu-Daudé bool sdbus_get_cmd_line(SDBus *sdbus);
160c759a790SPeter Maydell int sdbus_do_command(SDBus *sd, SDRequest *req, uint8_t *response);
16139017143SPhilippe Mathieu-Daudé /**
16239017143SPhilippe Mathieu-Daudé  * Write a byte to a SD bus.
16339017143SPhilippe Mathieu-Daudé  * @sd: bus
16439017143SPhilippe Mathieu-Daudé  * @value: byte to write
16539017143SPhilippe Mathieu-Daudé  *
16639017143SPhilippe Mathieu-Daudé  * Write a byte on the data lines of a SD bus.
16739017143SPhilippe Mathieu-Daudé  */
16839017143SPhilippe Mathieu-Daudé void sdbus_write_byte(SDBus *sd, uint8_t value);
1698467f622SPhilippe Mathieu-Daudé /**
1708467f622SPhilippe Mathieu-Daudé  * Read a byte from a SD bus.
1718467f622SPhilippe Mathieu-Daudé  * @sd: bus
1728467f622SPhilippe Mathieu-Daudé  *
1738467f622SPhilippe Mathieu-Daudé  * Read a byte from the data lines of a SD bus.
1748467f622SPhilippe Mathieu-Daudé  *
1758467f622SPhilippe Mathieu-Daudé  * Return: byte value read
1768467f622SPhilippe Mathieu-Daudé  */
1778467f622SPhilippe Mathieu-Daudé uint8_t sdbus_read_byte(SDBus *sd);
178e35c343dSPhilippe Mathieu-Daudé /**
179e35c343dSPhilippe Mathieu-Daudé  * Write data to a SD bus.
180e35c343dSPhilippe Mathieu-Daudé  * @sdbus: bus
181e35c343dSPhilippe Mathieu-Daudé  * @buf: data to write
182e35c343dSPhilippe Mathieu-Daudé  * @length: number of bytes to write
183e35c343dSPhilippe Mathieu-Daudé  *
184e35c343dSPhilippe Mathieu-Daudé  * Write multiple bytes of data on the data lines of a SD bus.
185e35c343dSPhilippe Mathieu-Daudé  */
186e35c343dSPhilippe Mathieu-Daudé void sdbus_write_data(SDBus *sdbus, const void *buf, size_t length);
1876505a91aSPhilippe Mathieu-Daudé /**
1886505a91aSPhilippe Mathieu-Daudé  * Read data from a SD bus.
1896505a91aSPhilippe Mathieu-Daudé  * @sdbus: bus
1906505a91aSPhilippe Mathieu-Daudé  * @buf: buffer to read data into
1916505a91aSPhilippe Mathieu-Daudé  * @length: number of bytes to read
1926505a91aSPhilippe Mathieu-Daudé  *
1936505a91aSPhilippe Mathieu-Daudé  * Read multiple bytes of data on the data lines of a SD bus.
1946505a91aSPhilippe Mathieu-Daudé  */
1956505a91aSPhilippe Mathieu-Daudé void sdbus_read_data(SDBus *sdbus, void *buf, size_t length);
196995731d3SBin Meng bool sdbus_receive_ready(SDBus *sd);
197c759a790SPeter Maydell bool sdbus_data_ready(SDBus *sd);
198c759a790SPeter Maydell bool sdbus_get_inserted(SDBus *sd);
199c759a790SPeter Maydell bool sdbus_get_readonly(SDBus *sd);
20097fb87ccSClement Deschamps /**
20197fb87ccSClement Deschamps  * sdbus_reparent_card: Reparent an SD card from one controller to another
20297fb87ccSClement Deschamps  * @from: controller bus to remove card from
20397fb87ccSClement Deschamps  * @to: controller bus to move card to
20497fb87ccSClement Deschamps  *
20597fb87ccSClement Deschamps  * Reparent an SD card, effectively unplugging it from one controller
20697fb87ccSClement Deschamps  * and inserting it into another. This is useful for SoCs like the
20797fb87ccSClement Deschamps  * bcm2835 which have two SD controllers and connect a single SD card
20897fb87ccSClement Deschamps  * to them, selected by the guest reprogramming GPIO line routing.
20997fb87ccSClement Deschamps  */
21097fb87ccSClement Deschamps void sdbus_reparent_card(SDBus *from, SDBus *to);
211c759a790SPeter Maydell 
212c759a790SPeter Maydell /* Functions to be used by SD devices to report back to qdevified controllers */
213c759a790SPeter Maydell void sdbus_set_inserted(SDBus *sd, bool inserted);
214c759a790SPeter Maydell void sdbus_set_readonly(SDBus *sd, bool inserted);
215c759a790SPeter Maydell 
2162a6a4076SMarkus Armbruster #endif /* HW_SD_H */
217