1.1 --- a/pkg/devices/lib/msc/src/common.cc Fri Feb 16 23:11:25 2024 +0100
1.2 +++ b/pkg/devices/lib/msc/src/common.cc Sat Feb 17 23:04:12 2024 +0100
1.3 @@ -23,515 +23,11 @@
1.4 #include <l4/sys/irq.h>
1.5 #include <l4/util/util.h>
1.6
1.7 +#include <math.h>
1.8 #include <stdio.h>
1.9
1.10 #include "msc-common.h"
1.11 -
1.12 -
1.13 -
1.14 -// Register locations for each channel.
1.15 -
1.16 -enum Regs : unsigned
1.17 -{
1.18 - Msc_control = 0x000, // MSC_CTRL
1.19 - Msc_status = 0x004, // MSC_STAT
1.20 - Msc_clock_rate = 0x008, // MSC_CLKRT
1.21 - Msc_command_data_control = 0x00c, // MSC_CMDAT
1.22 - Msc_response_timeout = 0x010, // MSC_RESTO
1.23 - Msc_read_timeout = 0x014, // MSC_RDTO
1.24 - Msc_block_length = 0x018, // MSC_BLKLEN
1.25 - Msc_block_count = 0x01c, // MSC_NOB
1.26 - Msc_block_success_count = 0x020, // MSC_SNOB
1.27 - Msc_interrupt_mask = 0x024, // MSC_IMASK
1.28 - Msc_interrupt_flag = 0x028, // MSC_IFLG/MSC_IREG
1.29 - Msc_command_index = 0x02c, // MSC_CMD
1.30 - Msc_command_argument = 0x030, // MSC_ARG
1.31 - Msc_response_fifo = 0x034, // MSC_RES
1.32 - Msc_recv_data_fifo = 0x038, // MSC_RXFIFO
1.33 - Msc_trans_data_fifo = 0x03c, // MSC_TXFIFO
1.34 -
1.35 - // JZ4780/X1600 only.
1.36 -
1.37 - Msc_low_power_mode = 0x040, // MSC_LPM
1.38 - Msc_dma_control = 0x044, // MSC_DMAC
1.39 - Msc_dma_descriptor_address = 0x048, // MSC_DMANDA
1.40 - Msc_dma_data_address = 0x04c, // MSC_DMADA
1.41 - Msc_dma_data_length = 0x050, // MSC_DMALEN
1.42 - Msc_dma_command = 0x054, // MSC_DMACMD
1.43 - Msc_control2 = 0x058, // MSC_CTRL2
1.44 - Msc_rtfifo_data_counter = 0x05c, // MSC_RTCNT
1.45 -
1.46 - // Channel block size/offset.
1.47 -
1.48 - Msc_channel_offset = 0x10000,
1.49 -};
1.50 -
1.51 -// Field definitions.
1.52 -
1.53 -enum Control_bits : unsigned
1.54 -{
1.55 - // JZ4780/X1600 only.
1.56 -
1.57 - Control_send_ccsd = 0x8000, // SEND_CCSD
1.58 - Control_send_ccsd_automatically = 0x4000, // SEND_CCSD
1.59 -
1.60 - // Common.
1.61 -
1.62 - Control_exit_multiple = 0x0080, // EXIT_MULTIPLE
1.63 - Control_exit_transfer = 0x0040, // EXIT_TRANSFER
1.64 - Control_start_read_wait = 0x0020, // START_READ_WAIT
1.65 - Control_stop_read_wait = 0x0010, // STOP_READ_WAIT
1.66 - Control_reset = 0x0008, // RESET
1.67 - Control_start_operation = 0x0004, // START_OP
1.68 -
1.69 - Control_clock_control_field_mask = 0x3, // CLOCK_CTRL
1.70 - Control_clock_control_start = 2,
1.71 - Control_clock_control_stop = 1,
1.72 - Control_clock_control_field_shift = 0,
1.73 -};
1.74 -
1.75 -enum Control2_bits : unsigned
1.76 -{
1.77 - // JZ4780/X1600 only.
1.78 -
1.79 - Control2_pin_level_polarity_field_mask = 0x1f, // PIP
1.80 - Control2_pin_level_polarity_field_shift = 24,
1.81 -
1.82 - // JZ4780 only.
1.83 -
1.84 - Control2_reset_enable = 0x00800000, // RST_EN
1.85 -
1.86 - // JZ4780/X1600 only.
1.87 -
1.88 - Control2_stop_read_operation_mode = 0x00000010, // STPRM
1.89 -
1.90 - // JZ4780 only.
1.91 -
1.92 - Control2_signal_voltage_change = 0x00000008, // SVC
1.93 -
1.94 - // JZ4780/X1600 only.
1.95 -
1.96 - Control2_speed_mode_field_mask = 0x7, // SMS
1.97 - Control2_speed_mode_default = 0, // = 0
1.98 - Control2_speed_mode_high = 1, // = 1
1.99 - Control2_speed_mode_sdr12 = 2, // = 2
1.100 - Control2_speed_mode_sdr25 = 3, // = 3
1.101 - Control2_speed_mode_sdr50 = 4, // = 4
1.102 - Control2_speed_mode_field_shift = 0,
1.103 -};
1.104 -
1.105 -enum Status_bits : unsigned
1.106 -{
1.107 - // JZ4780/X1600 only.
1.108 -
1.109 - Status_auto_cmd12_done = 0x80000000, // AUTO_CMD12_DONE
1.110 -
1.111 - // JZ4780 only.
1.112 -
1.113 - Status_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE
1.114 - Status_signal_voltage_change = 0x20000000, // SVS
1.115 -
1.116 - // JZ4780/X1600 only.
1.117 -
1.118 - Status_pin_level_field_mask = 0x1f, // PIN_LEVEL
1.119 - Status_pin_level_field_shift = 24,
1.120 -
1.121 - Status_boot_crc_error = 0x00100000, // BCE
1.122 - Status_boot_data_end = 0x00080000, // BDE
1.123 - Status_boot_ack_error = 0x00040000, // BAE
1.124 - Status_boot_ack_received = 0x00020000, // BAR
1.125 - Status_dma_end = 0x00010000, // DMAEND
1.126 -
1.127 - // Common.
1.128 -
1.129 - Status_resetting = 0x8000, // IS_RESETTING
1.130 - Status_sdio_interrupt_active = 0x4000, // SDIO_INT_ACTIVE
1.131 - Status_programming_done = 0x2000, // PRG_DONE
1.132 - Status_data_transfer_done = 0x1000, // DATA_TRAN_DONE
1.133 - Status_end_command_response = 0x0800, // END_CMD_RES
1.134 - Status_data_fifo_almost_full = 0x0400, // DATA_FIFO_AFULL
1.135 - Status_read_wait = 0x0200, // IS_READWAIT
1.136 - Status_clock_enabled = 0x0100, // CLK_EN
1.137 - Status_data_fifo_full = 0x0080, // DATA_FIFO_FULL
1.138 - Status_data_fifo_empty = 0x0040, // DATA_FIFO_EMPTY
1.139 - Status_response_crc_error = 0x0020, // CRC_RES_ERR
1.140 - Status_read_crc_error = 0x0010, // CRC_READ_ERROR
1.141 - Status_write_crc_error_no_status = 0x0008, // CRC_WRITE_ERROR (2)
1.142 - Status_write_crc_error_data = 0x0004, // CRC_WRITE_ERROR (1)
1.143 - Status_timeout_response = 0x0002, // TIME_OUT_RES
1.144 - Status_timeout_read = 0x0001, // TIME_OUT_READ
1.145 -};
1.146 -
1.147 -enum Clock_rate_bits : unsigned
1.148 -{
1.149 - Clock_rate_field_mask = 0x7, // CLK_RATE
1.150 - Clock_rate_field_shift = 0,
1.151 -};
1.152 -
1.153 -enum Command_data_control_bits : unsigned
1.154 -{
1.155 - // JZ4780/X1600 only.
1.156 -
1.157 - Cdc_ccs_expected = 0x80000000, // CCS_EXPECTED
1.158 - Cdc_read_ce_ata = 0x40000000, // READ_CEATA
1.159 - Cdc_disable_boot = 0x08000000, // DIS_BOOT
1.160 - Cdc_expect_boot_ack = 0x02000000, // EXP_BOOT_ACK
1.161 - Cdc_alternative_boot_mode = 0x01000000, // BOOT_MODE
1.162 -
1.163 - // JZ4780 only.
1.164 -
1.165 - Cdc_auto_cmd23 = 0x00040000, // AUTO_CMD23
1.166 -
1.167 - // JZ4780/X1600 only.
1.168 -
1.169 - Cdc_sdio_interrupt_2cycle = 0x00020000, // SDIO_PRDT
1.170 - Cdc_auto_cmd12 = 0x00010000, // AUTO_CMD12
1.171 -
1.172 - Cdc_recv_fifo_level_field_mask = 0x3, // RTRG
1.173 - Cdc_fifo_level_16 = 0,
1.174 - Cdc_fifo_level_32 = 1,
1.175 - Cdc_fifo_level_64 = 2,
1.176 - Cdc_fifo_level_96 = 3,
1.177 - Cdc_recv_fifo_level_field_shift = 14,
1.178 -
1.179 - Cdc_trans_fifo_level_field_mask = 0x3, // TTRG
1.180 - Cdc_trans_fifo_level_field_shift = 12,
1.181 -
1.182 - // Common.
1.183 -
1.184 - Cdc_io_abort = 0x0800, // IO_ABORT
1.185 -
1.186 - Cdc_bus_width_field_mask = 0x3, // BUS_WIDTH
1.187 - Cdc_bus_width_field_1bit = 0, // = 0
1.188 - Cdc_bus_width_field_4bit = 2, // = 2
1.189 - Cdc_bus_width_field_shift = 9,
1.190 -
1.191 - // JZ4740 only.
1.192 -
1.193 - Cdc_dma_enable = 0x0100, // DMA_EN
1.194 - Cdc_dma_disable = 0x0000,
1.195 -
1.196 - // Common.
1.197 -
1.198 - Cdc_init_sequence = 0x0080, // INIT
1.199 -
1.200 - Cdc_expect_busy = 0x0040, // BUSY
1.201 - Cdc_do_not_expect_busy = 0x0000,
1.202 -
1.203 - Cdc_stream_block = 0x0020, // STREAM_BLOCK
1.204 - Cdc_not_stream_block = 0x0000,
1.205 -
1.206 - Cdc_write_operation = 0x0010, // WRITE_READ
1.207 - Cdc_read_operation = 0x0000,
1.208 -
1.209 - Cdc_data_with_command = 0x0008, // DATA_EN
1.210 - Cdc_no_data_with_command = 0x0000,
1.211 -
1.212 - Cdc_response_format_field_mask = 0x7, // RESPONSE_FORMAT
1.213 - Cdc_response_format_field_shift = 0,
1.214 -};
1.215 -
1.216 -enum Response_timeout_bits : unsigned
1.217 -{
1.218 - // NOTE: 16-bit value in the JZ4780.
1.219 - // NOTE: 32-bit value in the X1600.
1.220 -
1.221 - Response_timeout_mask = 0x000000ff, // RES_TO
1.222 -};
1.223 -
1.224 -enum Read_timeout_bits : unsigned
1.225 -{
1.226 - // NOTE: 16-bit value prior to the JZ4780/X1600.
1.227 -
1.228 - Read_timeout_mask = 0xffffffff, // READ_TO
1.229 -};
1.230 -
1.231 -enum Block_length_bits : unsigned
1.232 -{
1.233 - // NOTE: 16-bit value in the JZ4780/X1600.
1.234 -
1.235 - Block_length_mask = 0x00000fff, // BLK_LEN
1.236 -};
1.237 -
1.238 -enum Block_count_bits : unsigned
1.239 -{
1.240 - Block_count_mask = 0x0000ffff, // NOB/SNOB
1.241 -};
1.242 -
1.243 -// Interrupt mask/flag bits.
1.244 -
1.245 -enum Interrupt_bits : unsigned
1.246 -{
1.247 - // X1600 only.
1.248 -
1.249 - Int_dma_data_done = 0x80000000, // DMA_DATA_DONE
1.250 -
1.251 - // JZ4780 only.
1.252 -
1.253 - Int_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE
1.254 - Int_signal_voltage_change = 0x20000000, // SVS
1.255 -
1.256 - // JZ4780/X1600 only.
1.257 -
1.258 - Int_pin_level_field_mask = 0x1f, // PIN_LEVEL
1.259 - Int_pin_level_field_shift = 24,
1.260 -
1.261 - // X1600 only.
1.262 -
1.263 - Int_write_request_all_done = 0x00800000, // WR_ALL_DONE
1.264 -
1.265 - // JZ4780/X1600 only.
1.266 -
1.267 - Int_boot_crc_error = 0x00100000, // BCE
1.268 - Int_boot_data_end = 0x00080000, // BDE
1.269 - Int_boot_ack_error = 0x00040000, // BAE
1.270 - Int_boot_ack_received = 0x00020000, // BAR
1.271 - Int_dma_end = 0x00010000, // DMAEND
1.272 - Int_auto_cmd12_done = 0x00008000, // AUTO_CMD12_DONE
1.273 - Int_data_fifo_full = 0x00004000, // DATA_FIFO_FULL
1.274 - Int_data_fifo_empty = 0x00002000, // DATA_FIFO_EMP
1.275 - Int_crc_response_error = 0x00001000, // CRC_RES_ERR
1.276 - Int_crc_read_error = 0x00000800, // CRC_READ_ERR
1.277 - Int_crc_write_error = 0x00000400, // CRC_WRITE_ERR
1.278 - Int_response_timeout = 0x00000200, // TIME_OUT_RES
1.279 - Int_read_timeout = 0x00000100, // TIME_OUT_READ
1.280 -
1.281 - // Common.
1.282 -
1.283 - Int_sdio = 0x80, // SDIO
1.284 - Int_trans_fifo_write_request = 0x40, // TXFIFO_WR_REQ
1.285 - Int_recv_fifo_read_request = 0x20, // RXFIFO_RD_REQ
1.286 - Int_end_command_response = 0x04, // END_CMD_RES
1.287 - Int_programming_done = 0x02, // PRG_DONE
1.288 - Int_data_transfer_done = 0x01, // DATA_TRAN_DONE
1.289 -};
1.290 -
1.291 -enum Command_index_bits : unsigned
1.292 -{
1.293 - Command_index_mask = 0x0000003f, // CMD_INDEX
1.294 -};
1.295 -
1.296 -enum Command_argument_bits : unsigned
1.297 -{
1.298 - Command_argument_mask = 0xffffffff, // ARG
1.299 -};
1.300 -
1.301 -enum Response_fifo_bits : unsigned
1.302 -{
1.303 - Response_fifo_mask = 0x0000ffff, // DATA
1.304 -};
1.305 -
1.306 -enum Recv_data_fifo_bits : unsigned
1.307 -{
1.308 - Recv_data_fifo_mask = 0xffffffff, // DATA
1.309 -};
1.310 -
1.311 -enum Trans_data_fifo_bits : unsigned
1.312 -{
1.313 - Trans_data_fifo_mask = 0xffffffff, // DATA
1.314 -};
1.315 -
1.316 -enum Low_power_mode_bits : unsigned
1.317 -{
1.318 - Low_power_mode_enable = 0x00000001, // LPM
1.319 -};
1.320 -
1.321 -enum Dma_control_bits : unsigned
1.322 -{
1.323 - Dma_mode_specify_transfer_length = 0x80, // MODE_SEL
1.324 -
1.325 - Dma_address_offset_field_mask = 0x3, // AOFST
1.326 - Dma_address_offset_field_shift = 5,
1.327 -
1.328 - Dma_align_enable = 0x10, // ALIGNEN
1.329 -
1.330 - Dma_burst_type_field_mask = 0x3, // INCR
1.331 - Dma_burst_type_incr16 = 0,
1.332 - Dma_burst_type_incr32 = 1,
1.333 - Dma_burst_type_incr64 = 2,
1.334 - Dma_burst_type_field_shift = 2,
1.335 -
1.336 - Dma_select_common_dma = 0x02, // DMASEL
1.337 - Dma_select_special_dma = 0x00,
1.338 -
1.339 - Dma_enable = 0x01, // DMAEN
1.340 - Dma_disable = 0x00,
1.341 -};
1.342 -
1.343 -
1.344 -
1.345 -// Command indexes.
1.346 -
1.347 -enum Command_index : unsigned
1.348 -{
1.349 - Command_go_idle_state = 0,
1.350 - Command_send_op_cond = 1,
1.351 - Command_all_send_cid = 2,
1.352 - Command_send_relative_addr = 3, // SD
1.353 - Command_set_relative_addr = 3, // MMC
1.354 - Command_set_dsr = 4,
1.355 - Command_io_send_op_cond = 5, // SDIO
1.356 - Command_select_deselect_card = 7,
1.357 - Command_send_if_cond = 8,
1.358 - Command_send_csd = 9,
1.359 - Command_send_cid = 10,
1.360 - Command_read_dat_until_stop = 11,
1.361 - Command_stop_transmission = 12,
1.362 - Command_send_status = 13,
1.363 - Command_go_inactive_state = 15,
1.364 - Command_set_blocklen = 16,
1.365 - Command_read_single_block = 17,
1.366 - Command_read_multiple_block = 18,
1.367 - Command_write_dat_until_stop = 20,
1.368 - Command_set_block_count = 23,
1.369 - Command_write_block = 24,
1.370 - Command_write_multiple_block = 25,
1.371 - Command_program_cid = 26,
1.372 - Command_program_csd = 27,
1.373 - Command_set_write_prot = 28,
1.374 - Command_clr_write_prot = 29,
1.375 - Command_send_write_prot = 30,
1.376 - Command_tag_sector_start = 32,
1.377 - Command_tag_sector_end = 33,
1.378 - Command_untag_sector = 34,
1.379 - Command_tag_erase_group_start = 35,
1.380 - Command_tag_erase_group_end = 36,
1.381 - Command_untag_erase_group = 37,
1.382 - Command_erase = 38,
1.383 - Command_fast_io = 39,
1.384 - Command_go_irq_state = 40,
1.385 - Command_lock_unlock = 42,
1.386 - Command_io_rw_direct = 52, // SDIO
1.387 - Command_app_cmd = 55,
1.388 - Command_gen_cmd = 56,
1.389 -};
1.390 -
1.391 -// Application-specific command indexes, used by first issuing Command_app_cmd.
1.392 -
1.393 -enum App_command_index : unsigned
1.394 -{
1.395 - App_command_set_bus_width = 6,
1.396 - App_command_sd_status = 13,
1.397 - App_command_send_num_wr_blocks = 22,
1.398 - App_command_set_wr_block_erase_count = 23,
1.399 - App_command_sd_send_op_cond = 41,
1.400 - App_command_set_clr_card_detect = 42,
1.401 - App_command_send_scr = 51,
1.402 - App_command_read_ocr = 58,
1.403 -};
1.404 -
1.405 -enum Bus_width_bits : unsigned
1.406 -{
1.407 - Bus_width_1bit = 0,
1.408 - Bus_width_4bit = 2,
1.409 -};
1.410 -
1.411 -// Command response sizes in 16-bit units.
1.412 -
1.413 -enum Response_sizes : unsigned
1.414 -{
1.415 - Response_size_R1 = 3,
1.416 - Response_size_R2 = 8, // omits the CRC and end bit
1.417 - Response_size_R3 = 3,
1.418 - Response_size_R4 = 3,
1.419 - Response_size_R5 = 3,
1.420 - Response_size_R6 = 3,
1.421 - Response_size_R7 = 3,
1.422 -};
1.423 -
1.424 -// SD_SEND_OP_COND argument flags.
1.425 -
1.426 -enum Ocr_argument_flags : unsigned
1.427 -{
1.428 - Ocr_high_capacity_storage = 0x40000000,
1.429 -};
1.430 -
1.431 -// SD_SEND_OP_COND response flags (R3).
1.432 -
1.433 -enum Ocr_response_flags : unsigned
1.434 -{
1.435 - Ocr_card_powered_up = 0x80000000,
1.436 -};
1.437 -
1.438 -// R1 status flags.
1.439 -
1.440 -enum R1_status_flags : unsigned
1.441 -{
1.442 - R1_status_error_mask = 0xffff0000,
1.443 -};
1.444 -
1.445 -
1.446 -
1.447 -// MMC response structures.
1.448 -// These are 16-bit aligned to permit conversion to 16-bit arrays.
1.449 -
1.450 -struct R1
1.451 -{
1.452 - uint8_t end_crc;
1.453 - uint32_t status;
1.454 - uint8_t index:6, trans_start:2;
1.455 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.456 -
1.457 -struct R2
1.458 -{
1.459 - // uint8_t end_crc; (not retrieved)
1.460 -
1.461 - union
1.462 - {
1.463 - uint8_t raw[15];
1.464 - struct CID cid;
1.465 - struct CSD csd;
1.466 - } payload;
1.467 -
1.468 - uint8_t reserved_trans_start;
1.469 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.470 -
1.471 -struct R3
1.472 -{
1.473 - uint8_t end_reserved;
1.474 - uint32_t ocr;
1.475 - uint8_t reserved_trans_start;
1.476 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.477 -
1.478 -// SDIO response structures.
1.479 -
1.480 -struct R4
1.481 -{
1.482 - uint8_t end_reserved;
1.483 - uint32_t ocr:24, stuff:3, memory_present:1, number_io_functions:3, ready:1;
1.484 - uint8_t reserved_trans_start;
1.485 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.486 -
1.487 -struct R5
1.488 -{
1.489 - uint8_t end_crc;
1.490 - uint8_t data;
1.491 - uint8_t out_of_range:1, invalid_function_number:1, reserved:1, error:1,
1.492 - io_current_state:2, illegal_command:1, crc_error:1;
1.493 - uint16_t stuff;
1.494 - uint8_t index:6, trans_start:2;
1.495 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.496 -
1.497 -struct R6
1.498 -{
1.499 - uint8_t end_crc;
1.500 - uint16_t status;
1.501 - uint16_t rca;
1.502 - uint8_t index:6, trans_start:2;
1.503 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.504 -
1.505 -struct R7
1.506 -{
1.507 - uint8_t end_crc;
1.508 -
1.509 - union
1.510 - {
1.511 - uint32_t check:8, voltage:4, reserved:20;
1.512 - uint32_t raw;
1.513 - } check_voltage;
1.514 -
1.515 - uint8_t index:6, trans_start:2;
1.516 -} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.517 +#include "msc-defs.h"
1.518
1.519
1.520
1.521 @@ -580,8 +76,9 @@
1.522
1.523 // Channel abstraction.
1.524
1.525 -Msc_channel::Msc_channel(l4_addr_t msc_start, l4_addr_t addr, l4_cap_idx_t irq)
1.526 -: _msc_start(msc_start), _irq(irq)
1.527 +Msc_channel::Msc_channel(l4_addr_t msc_start, l4_addr_t addr, l4_cap_idx_t irq,
1.528 + Cpm_chip *cpm, enum Clock_identifiers clock)
1.529 +: _msc_start(msc_start), _irq(irq), _cpm(cpm), _clock(clock)
1.530 {
1.531 _regs = new Hw::Mmio_register_block<32>(addr);
1.532 }
1.533 @@ -606,6 +103,64 @@
1.534 }
1.535
1.536 bool
1.537 +Msc_channel::set_clock_frequency(uint64_t frequency)
1.538 +{
1.539 + uint64_t division = _cpm->get_frequency(_clock) / frequency;
1.540 + double divider = ceil(log2(division));
1.541 +
1.542 + if ((divider < 0) || (divider > Clock_rate_field_mask))
1.543 + return false;
1.544 +
1.545 + set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift,
1.546 + (uint32_t) divider);
1.547 +
1.548 + return true;
1.549 +}
1.550 +
1.551 +void
1.552 +Msc_channel::reset()
1.553 +{
1.554 + _regs[Msc_control] = _regs[Msc_control] | Control_reset;
1.555 +
1.556 + while (_regs[Msc_status] & Status_resetting);
1.557 +}
1.558 +
1.559 +void
1.560 +Msc_channel::start_clock()
1.561 +{
1.562 + set_field(Msc_control, Control_clock_control_field_mask,
1.563 + Control_clock_control_field_shift, Control_clock_control_start);
1.564 +
1.565 + while (!(_regs[Msc_status] & Status_clock_enabled));
1.566 +}
1.567 +
1.568 +void
1.569 +Msc_channel::stop_clock()
1.570 +{
1.571 + set_field(Msc_control, Control_clock_control_field_mask,
1.572 + Control_clock_control_field_shift, Control_clock_control_stop);
1.573 +
1.574 + while (_regs[Msc_status] & Status_clock_enabled);
1.575 +}
1.576 +
1.577 +void
1.578 +Msc_channel::ack_irq(uint32_t flags)
1.579 +{
1.580 + // Clear the flags by setting them.
1.581 +
1.582 + _regs[Msc_interrupt_flag] = _regs[Msc_interrupt_flag] | flags;
1.583 +}
1.584 +
1.585 +void
1.586 +Msc_channel::unmask_irq(uint32_t flags)
1.587 +{
1.588 + ack_irq(flags);
1.589 +
1.590 + if (_regs[Msc_interrupt_mask] & flags)
1.591 + _regs[Msc_interrupt_mask] = _regs[Msc_interrupt_mask] & ~flags;
1.592 +}
1.593 +
1.594 +bool
1.595 Msc_channel::command_will_write(uint8_t index)
1.596 {
1.597 // NOTE: Probably incomplete coverage.
1.598 @@ -765,55 +320,6 @@
1.599 }
1.600 }
1.601
1.602 -void
1.603 -Msc_channel::ack_irq(uint32_t flags)
1.604 -{
1.605 - // Clear the flags by setting them.
1.606 -
1.607 - _regs[Msc_interrupt_flag] = _regs[Msc_interrupt_flag] | flags;
1.608 -}
1.609 -
1.610 -void
1.611 -Msc_channel::unmask_irq(uint32_t flags)
1.612 -{
1.613 - ack_irq(flags);
1.614 -
1.615 - if (_regs[Msc_interrupt_mask] & flags)
1.616 - _regs[Msc_interrupt_mask] = _regs[Msc_interrupt_mask] & ~flags;
1.617 -}
1.618 -
1.619 -void
1.620 -Msc_channel::reset()
1.621 -{
1.622 - _regs[Msc_control] = _regs[Msc_control] | Control_reset;
1.623 -
1.624 - // NOTE: X1600 and other recent SoCs only.
1.625 -
1.626 - _regs[Msc_control] = _regs[Msc_control] & ~Control_reset;
1.627 -
1.628 - // Sufficient for other SoCs...
1.629 -
1.630 - while (_regs[Msc_status] & Status_resetting);
1.631 -}
1.632 -
1.633 -void
1.634 -Msc_channel::start_clock()
1.635 -{
1.636 - set_field(Msc_control, Control_clock_control_field_mask,
1.637 - Control_clock_control_field_shift, Control_clock_control_start);
1.638 -
1.639 - while (!(_regs[Msc_status] & Status_clock_enabled));
1.640 -}
1.641 -
1.642 -void
1.643 -Msc_channel::stop_clock()
1.644 -{
1.645 - set_field(Msc_control, Control_clock_control_field_mask,
1.646 - Control_clock_control_field_shift, Control_clock_control_stop);
1.647 -
1.648 - while (_regs[Msc_status] & Status_clock_enabled);
1.649 -}
1.650 -
1.651 // Send an application-specific command.
1.652
1.653 bool
1.654 @@ -1188,9 +694,10 @@
1.655 reset();
1.656
1.657 // Slow the clock for initialisation.
1.658 - // NOTE: Should use the CPM module to deduce the appropriate divider value.
1.659 + // NOTE: Should produce an error.
1.660
1.661 - set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 7);
1.662 + if (!set_clock_frequency(400000))
1.663 + return;
1.664
1.665 send_command(Command_go_idle_state, 0);
1.666
1.667 @@ -1204,11 +711,6 @@
1.668 identify_cards();
1.669 query_cards();
1.670
1.671 - // Restore the clock.
1.672 - // NOTE: Should use the CPM module to deduce the appropriate divider value.
1.673 -
1.674 - set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 1);
1.675 -
1.676 // Initially, no card is selected.
1.677
1.678 _card = -1;
1.679 @@ -1233,13 +735,16 @@
1.680 // Receive data from the selected card.
1.681
1.682 uint32_t
1.683 -Msc_channel::recv_data(l4re_dma_space_dma_addr_t paddr, uint32_t count)
1.684 +Msc_channel::recv_data(struct dma_region *region, uint32_t count)
1.685 {
1.686 + if (count > region->size)
1.687 + return 0;
1.688 +
1.689 uint32_t flags = Int_data_transfer_done;
1.690
1.691 unmask_irq(flags);
1.692
1.693 - uint32_t to_transfer = transfer(_msc_start + Msc_recv_data_fifo, paddr, true, count);
1.694 + uint32_t to_transfer = transfer(_msc_start + Msc_recv_data_fifo, region->paddr, true, count);
1.695
1.696 wait_for_irq(flags);
1.697 ack_irq(flags);
1.698 @@ -1255,13 +760,16 @@
1.699 // Send data to the selected card.
1.700
1.701 uint32_t
1.702 -Msc_channel::send_data(l4re_dma_space_dma_addr_t paddr, uint32_t count)
1.703 +Msc_channel::send_data(struct dma_region *region, uint32_t count)
1.704 {
1.705 + if (count > region->size)
1.706 + return 0;
1.707 +
1.708 uint32_t flags = Int_data_transfer_done;
1.709
1.710 unmask_irq(flags);
1.711
1.712 - uint32_t to_transfer = transfer(paddr, _msc_start + Msc_trans_data_fifo, false, count);
1.713 + uint32_t to_transfer = transfer(region->paddr, _msc_start + Msc_trans_data_fifo, false, count);
1.714
1.715 wait_for_irq(flags);
1.716 ack_irq(flags);
1.717 @@ -1277,7 +785,7 @@
1.718 // Read blocks from the indicated card into a memory region.
1.719
1.720 uint32_t
1.721 -Msc_channel::read_blocks(uint8_t card, l4re_dma_space_dma_addr_t paddr,
1.722 +Msc_channel::read_blocks(uint8_t card, struct dma_region *region,
1.723 uint32_t block_address, uint32_t block_count)
1.724 {
1.725 uint32_t block_size = 1 << _cards[card].csd.read_blocklen;
1.726 @@ -1287,6 +795,13 @@
1.727
1.728 if (_card != card)
1.729 {
1.730 + // Choose an appropriate clock frequency for the card.
1.731 + // NOTE: Should produce an error.
1.732 +
1.733 + if (!set_clock_frequency(_cards[card].csd.tran_speed == 0x32 ?
1.734 + 25000000 : 50000000))
1.735 + return 0;
1.736 +
1.737 if (!send_command(Command_select_deselect_card, _cards[card].rca << 16))
1.738 return 0;
1.739
1.740 @@ -1346,7 +861,7 @@
1.741
1.742 // NOTE: Use Msc_block_success_count instead.
1.743
1.744 - uint32_t transferred = recv_data(paddr, block_size * block_count);
1.745 + uint32_t transferred = recv_data(region, block_size * block_count);
1.746
1.747 if (block_count > 1)
1.748 send_command(Command_stop_transmission, 0);
1.749 @@ -1358,7 +873,8 @@
1.750
1.751 // Peripheral abstraction.
1.752
1.753 -Msc_chip::Msc_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end)
1.754 -: _msc_start(msc_start), _start(start), _end(end)
1.755 +Msc_chip::Msc_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end,
1.756 + Cpm_chip *cpm)
1.757 +: _msc_start(msc_start), _start(start), _end(end), _cpm(cpm)
1.758 {
1.759 }