1.1 --- a/pkg/devices/lib/msc/src/common.cc Fri Feb 16 00:55:51 2024 +0100
1.2 +++ b/pkg/devices/lib/msc/src/common.cc Fri Feb 16 23:11:25 2024 +0100
1.3 @@ -814,12 +814,6 @@
1.4 while (_regs[Msc_status] & Status_clock_enabled);
1.5 }
1.6
1.7 -uint32_t
1.8 -Msc_channel::get_status()
1.9 -{
1.10 - return _regs[Msc_status];
1.11 -}
1.12 -
1.13 // Send an application-specific command.
1.14
1.15 bool
1.16 @@ -946,45 +940,6 @@
1.17
1.18
1.19
1.20 -// Enable the controller and identify cards.
1.21 -
1.22 -void
1.23 -Msc_channel::enable()
1.24 -{
1.25 - // NOTE: X1600 and other recent SoCs only.
1.26 -
1.27 - _regs[Msc_low_power_mode] = _regs[Msc_low_power_mode] & ~Low_power_mode_enable;
1.28 -
1.29 - stop_clock();
1.30 - reset();
1.31 -
1.32 - // Slow the clock for initialisation.
1.33 - // NOTE: Should use the CPM module to deduce the appropriate divider value.
1.34 -
1.35 - set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 7);
1.36 -
1.37 - send_command(Command_go_idle_state, 0);
1.38 -
1.39 - if (check_sd())
1.40 - {
1.41 - init_sdio();
1.42 - init_sdmem();
1.43 - }
1.44 -
1.45 - init_mmc();
1.46 - identify_cards();
1.47 - query_cards();
1.48 -
1.49 - // Restore the clock.
1.50 - // NOTE: Should use the CPM module to deduce the appropriate divider value.
1.51 -
1.52 - set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 1);
1.53 -
1.54 - // Initially, no card is selected.
1.55 -
1.56 - _card = -1;
1.57 -}
1.58 -
1.59 // Check the voltage range of the SD card, potentially establishing that it is
1.60 // a high capacity card. Return false if the voltage range is incompatible.
1.61
1.62 @@ -1173,37 +1128,39 @@
1.63
1.64 _cards[card].csd = r2.payload.csd;
1.65
1.66 + struct CSD *csd = &_cards[card].csd;
1.67 +
1.68 printf("card: %d\n", card);
1.69 - printf("csd: %d\n", r2.payload.csd.csd);
1.70 - printf("copy: %s\n", r2.payload.csd.copy ? "copied" : "original");
1.71 - printf("card command classes: %03x\n", r2.payload.csd.card_command_classes);
1.72 - printf("device (size multiplier): %d %d\n", r2.payload.csd.device_size + 1,
1.73 - 1 << (r2.payload.csd.device_size_multiplier + 2));
1.74 - printf("device size: %d\n", (1 << r2.payload.csd.read_blocklen) *
1.75 - (r2.payload.csd.device_size + 1) *
1.76 - (1 << (r2.payload.csd.device_size_multiplier + 2)));
1.77 - printf("transfer speed: %d MHz\n", r2.payload.csd.tran_speed == 0x32 ? 25 : 50);
1.78 - printf("format group: %d %d\n", r2.payload.csd.format, r2.payload.csd.format_group);
1.79 - printf("write time factor: %d\n", 1 << r2.payload.csd.write_time_factor);
1.80 - printf("write protect (temp perm): %s %s\n", r2.payload.csd.temp_write_prot ? "yes" : "no",
1.81 - r2.payload.csd.perm_write_prot ? "yes" : "no");
1.82 - printf("write protect group (enable size): %s %d\n", r2.payload.csd.write_prot_group_enable ? "yes" : "no",
1.83 - r2.payload.csd.write_prot_group_size + 1);
1.84 - printf("write block (partial length): %s %d\n", r2.payload.csd.write_block_partial ? "yes" : "no",
1.85 - 1 << r2.payload.csd.write_blocklen);
1.86 - printf("read block (partial length): %s %d\n", r2.payload.csd.read_block_partial ? "yes" : "no",
1.87 - 1 << r2.payload.csd.read_blocklen);
1.88 - printf("erase: sector single: %d %s\n", r2.payload.csd.erase_sector_size + 1,
1.89 - r2.payload.csd.erase_single_block_enable ? "yes" : "no");
1.90 - printf("misalign: read write: %s %s\n", r2.payload.csd.read_block_misalign ? "yes" : "no",
1.91 - r2.payload.csd.write_block_misalign ? "yes" : "no");
1.92 - printf("max read current (min max): %d %d\n", r2.payload.csd.max_read_current_min,
1.93 - r2.payload.csd.max_read_current_max);
1.94 - printf("max write current (min max): %d %d\n", r2.payload.csd.max_write_current_min,
1.95 - r2.payload.csd.max_write_current_max);
1.96 - printf("read access time (1 2): %d %d\n", r2.payload.csd.data_read_access_time_1,
1.97 - r2.payload.csd.data_read_access_time_2);
1.98 - printf("DSR: %s\n", r2.payload.csd.dsr_implemented ? "yes" : "no");
1.99 + printf("csd: %d\n", csd->csd);
1.100 + printf("copy: %s\n", csd->copy ? "copied" : "original");
1.101 + printf("card command classes: %03x\n", csd->card_command_classes);
1.102 + printf("device (size multiplier): %d %d\n", csd->device_size + 1,
1.103 + 1 << (csd->device_size_multiplier + 2));
1.104 + printf("device size: %d\n", (1 << csd->read_blocklen) *
1.105 + (csd->device_size + 1) *
1.106 + (1 << (csd->device_size_multiplier + 2)));
1.107 + printf("transfer speed: %d MHz\n", csd->tran_speed == 0x32 ? 25 : 50);
1.108 + printf("format group: %d %d\n", csd->format, r2.payload.csd.format_group);
1.109 + printf("write time factor: %d\n", 1 << csd->write_time_factor);
1.110 + printf("write protect (temp perm): %s %s\n", csd->temp_write_prot ? "yes" : "no",
1.111 + csd->perm_write_prot ? "yes" : "no");
1.112 + printf("write protect group (enable size): %s %d\n", csd->write_prot_group_enable ? "yes" : "no",
1.113 + csd->write_prot_group_size + 1);
1.114 + printf("write block (partial length): %s %d\n", csd->write_block_partial ? "yes" : "no",
1.115 + 1 << csd->write_blocklen);
1.116 + printf("read block (partial length): %s %d\n", csd->read_block_partial ? "yes" : "no",
1.117 + 1 << csd->read_blocklen);
1.118 + printf("erase: sector single: %d %s\n", csd->erase_sector_size + 1,
1.119 + csd->erase_single_block_enable ? "yes" : "no");
1.120 + printf("misalign: read write: %s %s\n", csd->read_block_misalign ? "yes" : "no",
1.121 + csd->write_block_misalign ? "yes" : "no");
1.122 + printf("max read current (min max): %d %d\n", csd->max_read_current_min,
1.123 + csd->max_read_current_max);
1.124 + printf("max write current (min max): %d %d\n", csd->max_write_current_min,
1.125 + csd->max_write_current_max);
1.126 + printf("read access time (1 2): %d %d\n", csd->data_read_access_time_1,
1.127 + csd->data_read_access_time_2);
1.128 + printf("DSR: %s\n", csd->dsr_implemented ? "yes" : "no");
1.129
1.130 // Query the OCR again now that we can associate it with a specific card.
1.131
1.132 @@ -1218,6 +1175,61 @@
1.133
1.134
1.135
1.136 +// Enable the controller and identify cards.
1.137 +
1.138 +void
1.139 +Msc_channel::enable()
1.140 +{
1.141 + // NOTE: X1600 and other recent SoCs only.
1.142 +
1.143 + _regs[Msc_low_power_mode] = _regs[Msc_low_power_mode] & ~Low_power_mode_enable;
1.144 +
1.145 + stop_clock();
1.146 + reset();
1.147 +
1.148 + // Slow the clock for initialisation.
1.149 + // NOTE: Should use the CPM module to deduce the appropriate divider value.
1.150 +
1.151 + set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 7);
1.152 +
1.153 + send_command(Command_go_idle_state, 0);
1.154 +
1.155 + if (check_sd())
1.156 + {
1.157 + init_sdio();
1.158 + init_sdmem();
1.159 + }
1.160 +
1.161 + init_mmc();
1.162 + identify_cards();
1.163 + query_cards();
1.164 +
1.165 + // Restore the clock.
1.166 + // NOTE: Should use the CPM module to deduce the appropriate divider value.
1.167 +
1.168 + set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 1);
1.169 +
1.170 + // Initially, no card is selected.
1.171 +
1.172 + _card = -1;
1.173 +}
1.174 +
1.175 +// Obtain the card details.
1.176 +
1.177 +struct msc_card *
1.178 +Msc_channel::get_cards()
1.179 +{
1.180 + return _cards;
1.181 +}
1.182 +
1.183 +// Return the number of active cards.
1.184 +
1.185 +uint8_t
1.186 +Msc_channel::num_cards()
1.187 +{
1.188 + return _num_cards;
1.189 +}
1.190 +
1.191 // Receive data from the selected card.
1.192
1.193 uint32_t
1.194 @@ -1314,10 +1326,17 @@
1.195 _regs[Msc_block_count] = block_count;
1.196 _regs[Msc_block_length] = block_size;
1.197
1.198 - // NOTE: Where CCS = 0, byte addressing is used. Otherwise, block addressing is used.
1.199 + // Where CCS = 0, byte addressing is used. Otherwise, block addressing is used.
1.200 +
1.201 + uint32_t address;
1.202 +
1.203 + if (_cards[card].ocr & Ocr_high_capacity_storage)
1.204 + address = block_address;
1.205 + else
1.206 + address = block_address * block_size;
1.207
1.208 if (!send_command(block_count == 1 ? Command_read_single_block
1.209 - : Command_read_multiple_block, block_address))
1.210 + : Command_read_multiple_block, address))
1.211 return 0;
1.212
1.213 read_response((uint16_t *) &r1, Response_size_R1);