1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <zircon/compiler.h>
8 
9 #include <ddk/device.h>
10 #include <ddk/protocol/block.h>
11 #include <ddk/protocol/sdmmc.h>
12 #include <ddk/protocol/sdio.h>
13 #include <ddk/trace/event.h>
14 #include <hw/sdmmc.h>
15 
16 #include <stdbool.h>
17 
18 #include "sdio.h"
19 #include <threads.h>
20 
21 __BEGIN_CDECLS;
22 
23 typedef enum sdmmc_type {
24     SDMMC_TYPE_UNKNOWN,
25     SDMMC_TYPE_SD,
26     SDMMC_TYPE_MMC,
27     SDMMC_TYPE_SDIO,
28 } sdmmc_type_t;
29 
30 #define SDMMC_REQ_COUNT   16
31 
32 // If enabled, gather stats on concurrent io ops,
33 // pending txns, etc. Print them whenever the block
34 // info is queried (lsblk will provoke this)
35 #define WITH_STATS 1
36 
37 typedef struct sdmmc_device {
38     trace_async_id_t async_id;
39 
40     zx_device_t* zxdev;
41     zx_device_t* child_zxdev;
42 
43     sdmmc_protocol_t host;
44     sdmmc_host_info_t host_info;
45 
46     sdmmc_type_t type;
47 
48     sdmmc_bus_width_t bus_width;
49     sdmmc_voltage_t signal_voltage;
50     sdmmc_timing_t timing;
51 
52     unsigned clock_rate;    // Bus clock rate
53     uint64_t capacity;      // Card capacity
54 
55     uint16_t rca;           // Relative address
56 
57     // mmc
58     uint32_t raw_cid[4];
59     uint32_t raw_csd[4];
60     uint8_t raw_ext_csd[512];
61 
62     // sdio
63     sdio_device_t sdio_dev;
64 
65     mtx_t lock;
66 
67     // blockio requests
68     list_node_t txn_list;
69 
70     // outstanding request (1 right now)
71     sdmmc_req_t req;
72 
73     thrd_t worker_thread;
74     zx_handle_t worker_event;
75 
76     //Requires lock to be acquired.
77     //TODO(ravoorir): When converting to c++ use
78     //clang thread annotations.
79     bool worker_thread_started;
80     bool dead;
81 
82 #if WITH_STATS
83     size_t stat_concur;
84     size_t stat_pending;
85     size_t stat_max_concur;
86     size_t stat_max_pending;
87     size_t stat_total_ops;
88     size_t stat_total_blocks;
89 #endif
90 
91     block_info_t block_info;
92 } sdmmc_device_t;
93 
sdmmc_use_dma(sdmmc_device_t * dev)94 static inline bool sdmmc_use_dma(sdmmc_device_t* dev) {
95     return (dev->host_info.caps & (SDMMC_HOST_CAP_ADMA2 | SDMMC_HOST_CAP_SIXTY_FOUR_BIT));
96 }
97 
98 // SD/MMC shared ops
99 
100 zx_status_t sdmmc_go_idle(sdmmc_device_t* dev);
101 zx_status_t sdmmc_send_status(sdmmc_device_t* dev, uint32_t* response);
102 zx_status_t sdmmc_stop_transmission(sdmmc_device_t* dev);
103 
104 // SD ops
105 
106 zx_status_t sd_send_if_cond(sdmmc_device_t* dev);
107 
108 // SD/SDIO shared ops
109 zx_status_t sd_switch_uhs_voltage(sdmmc_device_t *dev, uint32_t ocr);
110 zx_status_t sd_send_relative_addr(sdmmc_device_t* dev, uint16_t *rca);
111 
112 // SDIO ops
113 zx_status_t sdio_send_op_cond(sdmmc_device_t* dev, uint32_t ocr, uint32_t* rocr);
114 zx_status_t sdio_io_rw_direct(sdmmc_device_t* dev, bool write, uint32_t fn_idx,
115                               uint32_t reg_addr, uint8_t write_byte, uint8_t *read_byte);
116 zx_status_t sdio_io_rw_extended(sdmmc_device_t *dev, bool write, uint32_t fn_idx,
117                                 uint32_t reg_addr, bool incr, uint32_t blk_count,
118                                 uint32_t blk_size,  bool use_dma, uint8_t *buf,
119                                 zx_handle_t dma_vmo, uint64_t buf_offset);
120 zx_status_t sdio_enable_interrupt(void *ctx, uint8_t fn_idx);
121 zx_status_t sdio_disable_interrupt(void *ctx, uint8_t fn_idx);
122 zx_status_t sdio_enable_function(void *ctx, uint8_t fn_idx);
123 zx_status_t sdio_disable_function(void *ctx, uint8_t fn_idx);
124 zx_status_t sdio_modify_block_size(void *ctx, uint8_t fn_idx, uint16_t blk_sz, bool deflt);
125 zx_status_t sdio_rw_data(void *ctx, uint8_t fn_idx, sdio_rw_txn_t *txn);
126 zx_status_t sdio_rw_byte(void *ctx, bool write, uint8_t fn_idx, uint32_t addr,
127                          uint8_t write_byte, uint8_t *read_byte);
128 zx_status_t sdio_get_device_hw_info(void *ctx, sdio_hw_info_t *dev_info);
129 zx_status_t sdio_get_cur_block_size(void *ctx, uint8_t fn_idx,
130                                     uint16_t *cur_blk_size);
131 
132 // MMC ops
133 
134 zx_status_t mmc_send_op_cond(sdmmc_device_t* dev, uint32_t ocr, uint32_t* rocr);
135 zx_status_t mmc_all_send_cid(sdmmc_device_t* dev, uint32_t cid[4]);
136 zx_status_t mmc_set_relative_addr(sdmmc_device_t* dev, uint16_t rca);
137 zx_status_t mmc_send_csd(sdmmc_device_t* dev, uint32_t csd[4]);
138 zx_status_t mmc_send_ext_csd(sdmmc_device_t* dev, uint8_t ext_csd[512]);
139 zx_status_t mmc_select_card(sdmmc_device_t* dev);
140 zx_status_t mmc_switch(sdmmc_device_t* dev, uint8_t index, uint8_t value);
141 
142 zx_status_t sdmmc_probe_sd(sdmmc_device_t* dev);
143 zx_status_t sdmmc_probe_mmc(sdmmc_device_t* dev);
144 zx_status_t sdmmc_probe_sdio(sdmmc_device_t* dev);
145 
146 __END_CDECLS;
147