xref: /openbmc/qemu/include/hw/sd/sd.h (revision fde3af1971f71a7b05dc6bcd6d1c9998b0b2c4c1)
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é 
78e3382ef0SSai Pavan Boddu typedef struct {
79e3382ef0SSai Pavan Boddu     uint8_t cmd;
80e3382ef0SSai Pavan Boddu     uint32_t arg;
81e3382ef0SSai Pavan Boddu     uint8_t crc;
82e3382ef0SSai Pavan Boddu } SDRequest;
83e3382ef0SSai Pavan Boddu 
84e3382ef0SSai Pavan Boddu 
85260bc9d8SPeter Maydell #define TYPE_SD_CARD "sd-card"
86a489d195SEduardo Habkost OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
87260bc9d8SPeter Maydell 
88c3287c0fSCédric Le Goater #define TYPE_SD_CARD_SPI "sd-card-spi"
89c3287c0fSCédric Le Goater DECLARE_INSTANCE_CHECKER(SDState, SD_CARD_SPI, TYPE_SD_CARD_SPI)
90c3287c0fSCédric Le Goater 
91*1b5a561cSPhilippe Mathieu-Daudé #define TYPE_EMMC "emmc"
92*1b5a561cSPhilippe Mathieu-Daudé DECLARE_INSTANCE_CHECKER(SDState, EMMC, TYPE_EMMC)
93*1b5a561cSPhilippe Mathieu-Daudé 
94db1015e9SEduardo Habkost struct SDCardClass {
95c759a790SPeter Maydell     /*< private >*/
96c759a790SPeter Maydell     DeviceClass parent_class;
97c759a790SPeter Maydell     /*< public >*/
98c759a790SPeter Maydell 
99c759a790SPeter Maydell     int (*do_command)(SDState *sd, SDRequest *req, uint8_t *response);
100c769a88dSPhilippe Mathieu-Daudé     /**
101c769a88dSPhilippe Mathieu-Daudé      * Write a byte to a SD card.
102c769a88dSPhilippe Mathieu-Daudé      * @sd: card
103c769a88dSPhilippe Mathieu-Daudé      * @value: byte to write
104c769a88dSPhilippe Mathieu-Daudé      *
105c769a88dSPhilippe Mathieu-Daudé      * Write a byte on the data lines of a SD card.
106c769a88dSPhilippe Mathieu-Daudé      */
107c769a88dSPhilippe Mathieu-Daudé     void (*write_byte)(SDState *sd, uint8_t value);
108c769a88dSPhilippe Mathieu-Daudé     /**
109c769a88dSPhilippe Mathieu-Daudé      * Read a byte from a SD card.
110c769a88dSPhilippe Mathieu-Daudé      * @sd: card
111c769a88dSPhilippe Mathieu-Daudé      *
112c769a88dSPhilippe Mathieu-Daudé      * Read a byte from the data lines of a SD card.
113c769a88dSPhilippe Mathieu-Daudé      *
114c769a88dSPhilippe Mathieu-Daudé      * Return: byte value read
115c769a88dSPhilippe Mathieu-Daudé      */
116c769a88dSPhilippe Mathieu-Daudé     uint8_t (*read_byte)(SDState *sd);
117995731d3SBin Meng     bool (*receive_ready)(SDState *sd);
118c759a790SPeter Maydell     bool (*data_ready)(SDState *sd);
1190034ebe6SPhilippe Mathieu-Daudé     void (*set_voltage)(SDState *sd, uint16_t millivolts);
120da346922SPhilippe Mathieu-Daudé     uint8_t (*get_dat_lines)(SDState *sd);
121da346922SPhilippe Mathieu-Daudé     bool (*get_cmd_line)(SDState *sd);
122c759a790SPeter Maydell     void (*enable)(SDState *sd, bool enable);
123c759a790SPeter Maydell     bool (*get_inserted)(SDState *sd);
124c759a790SPeter Maydell     bool (*get_readonly)(SDState *sd);
1255241b759SPhilippe Mathieu-Daudé     void (*set_cid)(SDState *sd);
1265241b759SPhilippe Mathieu-Daudé     void (*set_csd)(SDState *sd, uint64_t size);
1271b4a2342SPhilippe Mathieu-Daudé 
1281b4a2342SPhilippe Mathieu-Daudé     const struct SDProto *proto;
129db1015e9SEduardo Habkost };
130c759a790SPeter Maydell 
131c759a790SPeter Maydell #define TYPE_SD_BUS "sd-bus"
132c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(SDBus, SDBusClass,
13330b5707cSEduardo Habkost                     SD_BUS)
134c759a790SPeter Maydell 
135c759a790SPeter Maydell struct SDBus {
136c759a790SPeter Maydell     BusState qbus;
137c759a790SPeter Maydell };
138c759a790SPeter Maydell 
139db1015e9SEduardo Habkost struct SDBusClass {
140c759a790SPeter Maydell     /*< private >*/
141c759a790SPeter Maydell     BusClass parent_class;
142c759a790SPeter Maydell     /*< public >*/
143c759a790SPeter Maydell 
144c759a790SPeter Maydell     /* These methods are called by the SD device to notify the controller
145c759a790SPeter Maydell      * when the card insertion or readonly status changes
146c759a790SPeter Maydell      */
147c759a790SPeter Maydell     void (*set_inserted)(DeviceState *dev, bool inserted);
148c759a790SPeter Maydell     void (*set_readonly)(DeviceState *dev, bool readonly);
149db1015e9SEduardo Habkost };
150c759a790SPeter Maydell 
151c759a790SPeter Maydell /* Functions to be used by qdevified callers (working via
152c759a790SPeter Maydell  * an SDBus rather than directly with SDState)
153c759a790SPeter Maydell  */
1540034ebe6SPhilippe Mathieu-Daudé void sdbus_set_voltage(SDBus *sdbus, uint16_t millivolts);
155da346922SPhilippe Mathieu-Daudé uint8_t sdbus_get_dat_lines(SDBus *sdbus);
156da346922SPhilippe Mathieu-Daudé bool sdbus_get_cmd_line(SDBus *sdbus);
157c759a790SPeter Maydell int sdbus_do_command(SDBus *sd, SDRequest *req, uint8_t *response);
15839017143SPhilippe Mathieu-Daudé /**
15939017143SPhilippe Mathieu-Daudé  * Write a byte to a SD bus.
16039017143SPhilippe Mathieu-Daudé  * @sd: bus
16139017143SPhilippe Mathieu-Daudé  * @value: byte to write
16239017143SPhilippe Mathieu-Daudé  *
16339017143SPhilippe Mathieu-Daudé  * Write a byte on the data lines of a SD bus.
16439017143SPhilippe Mathieu-Daudé  */
16539017143SPhilippe Mathieu-Daudé void sdbus_write_byte(SDBus *sd, uint8_t value);
1668467f622SPhilippe Mathieu-Daudé /**
1678467f622SPhilippe Mathieu-Daudé  * Read a byte from a SD bus.
1688467f622SPhilippe Mathieu-Daudé  * @sd: bus
1698467f622SPhilippe Mathieu-Daudé  *
1708467f622SPhilippe Mathieu-Daudé  * Read a byte from the data lines of a SD bus.
1718467f622SPhilippe Mathieu-Daudé  *
1728467f622SPhilippe Mathieu-Daudé  * Return: byte value read
1738467f622SPhilippe Mathieu-Daudé  */
1748467f622SPhilippe Mathieu-Daudé uint8_t sdbus_read_byte(SDBus *sd);
175e35c343dSPhilippe Mathieu-Daudé /**
176e35c343dSPhilippe Mathieu-Daudé  * Write data to a SD bus.
177e35c343dSPhilippe Mathieu-Daudé  * @sdbus: bus
178e35c343dSPhilippe Mathieu-Daudé  * @buf: data to write
179e35c343dSPhilippe Mathieu-Daudé  * @length: number of bytes to write
180e35c343dSPhilippe Mathieu-Daudé  *
181e35c343dSPhilippe Mathieu-Daudé  * Write multiple bytes of data on the data lines of a SD bus.
182e35c343dSPhilippe Mathieu-Daudé  */
183e35c343dSPhilippe Mathieu-Daudé void sdbus_write_data(SDBus *sdbus, const void *buf, size_t length);
1846505a91aSPhilippe Mathieu-Daudé /**
1856505a91aSPhilippe Mathieu-Daudé  * Read data from a SD bus.
1866505a91aSPhilippe Mathieu-Daudé  * @sdbus: bus
1876505a91aSPhilippe Mathieu-Daudé  * @buf: buffer to read data into
1886505a91aSPhilippe Mathieu-Daudé  * @length: number of bytes to read
1896505a91aSPhilippe Mathieu-Daudé  *
1906505a91aSPhilippe Mathieu-Daudé  * Read multiple bytes of data on the data lines of a SD bus.
1916505a91aSPhilippe Mathieu-Daudé  */
1926505a91aSPhilippe Mathieu-Daudé void sdbus_read_data(SDBus *sdbus, void *buf, size_t length);
193995731d3SBin Meng bool sdbus_receive_ready(SDBus *sd);
194c759a790SPeter Maydell bool sdbus_data_ready(SDBus *sd);
195c759a790SPeter Maydell bool sdbus_get_inserted(SDBus *sd);
196c759a790SPeter Maydell bool sdbus_get_readonly(SDBus *sd);
19797fb87ccSClement Deschamps /**
19897fb87ccSClement Deschamps  * sdbus_reparent_card: Reparent an SD card from one controller to another
19997fb87ccSClement Deschamps  * @from: controller bus to remove card from
20097fb87ccSClement Deschamps  * @to: controller bus to move card to
20197fb87ccSClement Deschamps  *
20297fb87ccSClement Deschamps  * Reparent an SD card, effectively unplugging it from one controller
20397fb87ccSClement Deschamps  * and inserting it into another. This is useful for SoCs like the
20497fb87ccSClement Deschamps  * bcm2835 which have two SD controllers and connect a single SD card
20597fb87ccSClement Deschamps  * to them, selected by the guest reprogramming GPIO line routing.
20697fb87ccSClement Deschamps  */
20797fb87ccSClement Deschamps void sdbus_reparent_card(SDBus *from, SDBus *to);
208c759a790SPeter Maydell 
209c759a790SPeter Maydell /* Functions to be used by SD devices to report back to qdevified controllers */
210c759a790SPeter Maydell void sdbus_set_inserted(SDBus *sd, bool inserted);
211c759a790SPeter Maydell void sdbus_set_readonly(SDBus *sd, bool inserted);
212c759a790SPeter Maydell 
2132a6a4076SMarkus Armbruster #endif /* HW_SD_H */
214