1.1 --- a/pkg/devices/lib/msc/src/common.cc Sun Feb 11 00:39:56 2024 +0100
1.2 +++ b/pkg/devices/lib/msc/src/common.cc Sun Feb 11 18:47:06 2024 +0100
1.3 @@ -563,6 +563,21 @@
1.4
1.5
1.6
1.7 +// Utilities.
1.8 +
1.9 +static enum Command_data_control_bits
1.10 +encode_bus_width(uint8_t width)
1.11 +{
1.12 + switch (width)
1.13 + {
1.14 + case 4: return Cdc_bus_width_field_4bit;
1.15 + case 1: return Cdc_bus_width_field_1bit;
1.16 + default: return Cdc_bus_width_field_1bit;
1.17 + }
1.18 +}
1.19 +
1.20 +
1.21 +
1.22 // Channel abstraction.
1.23
1.24 Msc_channel::Msc_channel(l4_addr_t msc_start, l4_addr_t addr, l4_cap_idx_t irq)
1.25 @@ -608,6 +623,16 @@
1.26 }
1.27
1.28 bool
1.29 +Msc_channel::app_command_will_write(uint8_t index)
1.30 +{
1.31 + // NOTE: Probably incomplete coverage.
1.32 +
1.33 + (void) index;
1.34 +
1.35 + return false;
1.36 +}
1.37 +
1.38 +bool
1.39 Msc_channel::command_with_data(uint8_t index)
1.40 {
1.41 // NOTE: Probably incomplete coverage.
1.42 @@ -628,6 +653,20 @@
1.43 }
1.44
1.45 bool
1.46 +Msc_channel::app_command_with_data(uint8_t index)
1.47 +{
1.48 + // NOTE: Probably incomplete coverage.
1.49 +
1.50 + switch (index)
1.51 + {
1.52 + case App_command_sd_status: return true;
1.53 + case App_command_send_num_wr_blocks: return true;
1.54 + case App_command_send_scr: return true;
1.55 + default: return false;
1.56 + }
1.57 +}
1.58 +
1.59 +bool
1.60 Msc_channel::command_uses_busy(uint8_t index)
1.61 {
1.62 // NOTE: Probably incomplete coverage.
1.63 @@ -640,6 +679,16 @@
1.64 }
1.65 }
1.66
1.67 +bool
1.68 +Msc_channel::app_command_uses_busy(uint8_t index)
1.69 +{
1.70 + // NOTE: Probably incomplete coverage.
1.71 +
1.72 + (void) index;
1.73 +
1.74 + return false;
1.75 +}
1.76 +
1.77 uint8_t
1.78 Msc_channel::get_response_format(uint8_t index)
1.79 {
1.80 @@ -776,11 +825,13 @@
1.81 bool
1.82 Msc_channel::send_app_command(uint8_t index, uint32_t arg)
1.83 {
1.84 - if (!send_command(Command_app_cmd, 0, get_app_response_format(index),
1.85 - false, false, false))
1.86 + if (!send_command(Command_app_cmd, _current_rca << 16))
1.87 return false;
1.88
1.89 - return send_command(index, arg);
1.90 + return send_command(index, arg, get_app_response_format(index),
1.91 + app_command_with_data(index),
1.92 + app_command_will_write(index),
1.93 + app_command_uses_busy(index));
1.94 }
1.95
1.96 // Send a common MMC/SD command.
1.97 @@ -789,7 +840,8 @@
1.98 Msc_channel::send_command(uint8_t index, uint32_t arg)
1.99 {
1.100 return send_command(index, arg, get_response_format(index),
1.101 - command_with_data(index), command_will_write(index),
1.102 + command_with_data(index),
1.103 + command_will_write(index),
1.104 command_uses_busy(index));
1.105 }
1.106
1.107 @@ -821,7 +873,7 @@
1.108 // NOTE: May need to set the SD bus width.
1.109
1.110 set_field(Msc_command_data_control, Cdc_bus_width_field_mask,
1.111 - Cdc_bus_width_field_shift, Cdc_bus_width_field_1bit);
1.112 + Cdc_bus_width_field_shift, encode_bus_width(_current_bus_width));
1.113
1.114 set_field(Msc_command_data_control, Cdc_recv_fifo_level_field_mask,
1.115 Cdc_recv_fifo_level_field_shift, Cdc_fifo_level_16);
1.116 @@ -1075,6 +1127,10 @@
1.117 else
1.118 return;
1.119
1.120 + // Set the default bus width.
1.121 +
1.122 + _bus_width[_cards] = 0;
1.123 +
1.124 _cards++;
1.125 }
1.126 }
1.127 @@ -1167,13 +1223,19 @@
1.128 _current_rca = _rca[card];
1.129 }
1.130
1.131 -#if 0
1.132 - // NOTE: SMEM cards should allow bus width setting.
1.133 + // NOTE: SMEM cards should allow bus width setting with the SCR register
1.134 + // NOTE: describing the permitted values.
1.135 // NOTE: SDIO cards have their bus width set in CCCR via CMD52.
1.136
1.137 - printf("set bus width -> %s\n",
1.138 - send_app_command(App_command_set_bus_width, Bus_width_4bit) ? "set" : "not set");
1.139 -#endif
1.140 + if (!_bus_width[card])
1.141 + {
1.142 + if (send_app_command(App_command_set_bus_width, Bus_width_4bit))
1.143 + _bus_width[card] = 4;
1.144 + else
1.145 + _bus_width[card] = 1;
1.146 + }
1.147 +
1.148 + _current_bus_width = _bus_width[card];
1.149
1.150 if (!send_command(Command_set_blocklen, block_size))
1.151 return 0;