1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/pkg/devices/lib/msc/include/msc-defs.h Sat Feb 17 23:04:12 2024 +0100
1.3 @@ -0,0 +1,530 @@
1.4 +/*
1.5 + * MSC (MMC/SD controller) peripheral support.
1.6 + *
1.7 + * Copyright (C) 2024 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#pragma once
1.26 +
1.27 +#include <l4/devices/msc-common.h>
1.28 +
1.29 +
1.30 +
1.31 +// Register locations for each channel.
1.32 +
1.33 +enum Regs : unsigned
1.34 +{
1.35 + Msc_control = 0x000, // MSC_CTRL
1.36 + Msc_status = 0x004, // MSC_STAT
1.37 + Msc_clock_rate = 0x008, // MSC_CLKRT
1.38 + Msc_command_data_control = 0x00c, // MSC_CMDAT
1.39 + Msc_response_timeout = 0x010, // MSC_RESTO
1.40 + Msc_read_timeout = 0x014, // MSC_RDTO
1.41 + Msc_block_length = 0x018, // MSC_BLKLEN
1.42 + Msc_block_count = 0x01c, // MSC_NOB
1.43 + Msc_block_success_count = 0x020, // MSC_SNOB
1.44 + Msc_interrupt_mask = 0x024, // MSC_IMASK
1.45 + Msc_interrupt_flag = 0x028, // MSC_IFLG/MSC_IREG
1.46 + Msc_command_index = 0x02c, // MSC_CMD
1.47 + Msc_command_argument = 0x030, // MSC_ARG
1.48 + Msc_response_fifo = 0x034, // MSC_RES
1.49 + Msc_recv_data_fifo = 0x038, // MSC_RXFIFO
1.50 + Msc_trans_data_fifo = 0x03c, // MSC_TXFIFO
1.51 +
1.52 + // JZ4780/X1600 only.
1.53 +
1.54 + Msc_low_power_mode = 0x040, // MSC_LPM
1.55 + Msc_dma_control = 0x044, // MSC_DMAC
1.56 + Msc_dma_descriptor_address = 0x048, // MSC_DMANDA
1.57 + Msc_dma_data_address = 0x04c, // MSC_DMADA
1.58 + Msc_dma_data_length = 0x050, // MSC_DMALEN
1.59 + Msc_dma_command = 0x054, // MSC_DMACMD
1.60 + Msc_control2 = 0x058, // MSC_CTRL2
1.61 + Msc_rtfifo_data_counter = 0x05c, // MSC_RTCNT
1.62 +
1.63 + // Channel block size/offset.
1.64 +
1.65 + Msc_channel_offset = 0x10000,
1.66 +};
1.67 +
1.68 +// Field definitions.
1.69 +
1.70 +enum Control_bits : unsigned
1.71 +{
1.72 + // JZ4780/X1600 only.
1.73 +
1.74 + Control_send_ccsd = 0x8000, // SEND_CCSD
1.75 + Control_send_ccsd_automatically = 0x4000, // SEND_CCSD
1.76 +
1.77 + // Common.
1.78 +
1.79 + Control_exit_multiple = 0x0080, // EXIT_MULTIPLE
1.80 + Control_exit_transfer = 0x0040, // EXIT_TRANSFER
1.81 + Control_start_read_wait = 0x0020, // START_READ_WAIT
1.82 + Control_stop_read_wait = 0x0010, // STOP_READ_WAIT
1.83 + Control_reset = 0x0008, // RESET
1.84 + Control_start_operation = 0x0004, // START_OP
1.85 +
1.86 + Control_clock_control_field_mask = 0x3, // CLOCK_CTRL
1.87 + Control_clock_control_start = 2,
1.88 + Control_clock_control_stop = 1,
1.89 + Control_clock_control_field_shift = 0,
1.90 +};
1.91 +
1.92 +enum Control2_bits : unsigned
1.93 +{
1.94 + // JZ4780/X1600 only.
1.95 +
1.96 + Control2_pin_level_polarity_field_mask = 0x1f, // PIP
1.97 + Control2_pin_level_polarity_field_shift = 24,
1.98 +
1.99 + // JZ4780 only.
1.100 +
1.101 + Control2_reset_enable = 0x00800000, // RST_EN
1.102 +
1.103 + // JZ4780/X1600 only.
1.104 +
1.105 + Control2_stop_read_operation_mode = 0x00000010, // STPRM
1.106 +
1.107 + // JZ4780 only.
1.108 +
1.109 + Control2_signal_voltage_change = 0x00000008, // SVC
1.110 +
1.111 + // JZ4780/X1600 only.
1.112 +
1.113 + Control2_speed_mode_field_mask = 0x7, // SMS
1.114 + Control2_speed_mode_default = 0, // = 0
1.115 + Control2_speed_mode_high = 1, // = 1
1.116 + Control2_speed_mode_sdr12 = 2, // = 2
1.117 + Control2_speed_mode_sdr25 = 3, // = 3
1.118 + Control2_speed_mode_sdr50 = 4, // = 4
1.119 + Control2_speed_mode_field_shift = 0,
1.120 +};
1.121 +
1.122 +enum Status_bits : unsigned
1.123 +{
1.124 + // JZ4780/X1600 only.
1.125 +
1.126 + Status_auto_cmd12_done = 0x80000000, // AUTO_CMD12_DONE
1.127 +
1.128 + // JZ4780 only.
1.129 +
1.130 + Status_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE
1.131 + Status_signal_voltage_change = 0x20000000, // SVS
1.132 +
1.133 + // JZ4780/X1600 only.
1.134 +
1.135 + Status_pin_level_field_mask = 0x1f, // PIN_LEVEL
1.136 + Status_pin_level_field_shift = 24,
1.137 +
1.138 + Status_boot_crc_error = 0x00100000, // BCE
1.139 + Status_boot_data_end = 0x00080000, // BDE
1.140 + Status_boot_ack_error = 0x00040000, // BAE
1.141 + Status_boot_ack_received = 0x00020000, // BAR
1.142 + Status_dma_end = 0x00010000, // DMAEND
1.143 +
1.144 + // Common.
1.145 +
1.146 + Status_resetting = 0x8000, // IS_RESETTING
1.147 + Status_sdio_interrupt_active = 0x4000, // SDIO_INT_ACTIVE
1.148 + Status_programming_done = 0x2000, // PRG_DONE
1.149 + Status_data_transfer_done = 0x1000, // DATA_TRAN_DONE
1.150 + Status_end_command_response = 0x0800, // END_CMD_RES
1.151 + Status_data_fifo_almost_full = 0x0400, // DATA_FIFO_AFULL
1.152 + Status_read_wait = 0x0200, // IS_READWAIT
1.153 + Status_clock_enabled = 0x0100, // CLK_EN
1.154 + Status_data_fifo_full = 0x0080, // DATA_FIFO_FULL
1.155 + Status_data_fifo_empty = 0x0040, // DATA_FIFO_EMPTY
1.156 + Status_response_crc_error = 0x0020, // CRC_RES_ERR
1.157 + Status_read_crc_error = 0x0010, // CRC_READ_ERROR
1.158 + Status_write_crc_error_no_status = 0x0008, // CRC_WRITE_ERROR (2)
1.159 + Status_write_crc_error_data = 0x0004, // CRC_WRITE_ERROR (1)
1.160 + Status_timeout_response = 0x0002, // TIME_OUT_RES
1.161 + Status_timeout_read = 0x0001, // TIME_OUT_READ
1.162 +};
1.163 +
1.164 +enum Clock_rate_bits : unsigned
1.165 +{
1.166 + Clock_rate_field_mask = 0x7, // CLK_RATE
1.167 + Clock_rate_field_shift = 0,
1.168 +};
1.169 +
1.170 +enum Command_data_control_bits : unsigned
1.171 +{
1.172 + // JZ4780/X1600 only.
1.173 +
1.174 + Cdc_ccs_expected = 0x80000000, // CCS_EXPECTED
1.175 + Cdc_read_ce_ata = 0x40000000, // READ_CEATA
1.176 + Cdc_disable_boot = 0x08000000, // DIS_BOOT
1.177 + Cdc_expect_boot_ack = 0x02000000, // EXP_BOOT_ACK
1.178 + Cdc_alternative_boot_mode = 0x01000000, // BOOT_MODE
1.179 +
1.180 + // JZ4780 only.
1.181 +
1.182 + Cdc_auto_cmd23 = 0x00040000, // AUTO_CMD23
1.183 +
1.184 + // JZ4780/X1600 only.
1.185 +
1.186 + Cdc_sdio_interrupt_2cycle = 0x00020000, // SDIO_PRDT
1.187 + Cdc_auto_cmd12 = 0x00010000, // AUTO_CMD12
1.188 +
1.189 + Cdc_recv_fifo_level_field_mask = 0x3, // RTRG
1.190 + Cdc_fifo_level_16 = 0,
1.191 + Cdc_fifo_level_32 = 1,
1.192 + Cdc_fifo_level_64 = 2,
1.193 + Cdc_fifo_level_96 = 3,
1.194 + Cdc_recv_fifo_level_field_shift = 14,
1.195 +
1.196 + Cdc_trans_fifo_level_field_mask = 0x3, // TTRG
1.197 + Cdc_trans_fifo_level_field_shift = 12,
1.198 +
1.199 + // Common.
1.200 +
1.201 + Cdc_io_abort = 0x0800, // IO_ABORT
1.202 +
1.203 + Cdc_bus_width_field_mask = 0x3, // BUS_WIDTH
1.204 + Cdc_bus_width_field_1bit = 0, // = 0
1.205 + Cdc_bus_width_field_4bit = 2, // = 2
1.206 + Cdc_bus_width_field_shift = 9,
1.207 +
1.208 + // JZ4740 only.
1.209 +
1.210 + Cdc_dma_enable = 0x0100, // DMA_EN
1.211 + Cdc_dma_disable = 0x0000,
1.212 +
1.213 + // Common.
1.214 +
1.215 + Cdc_init_sequence = 0x0080, // INIT
1.216 +
1.217 + Cdc_expect_busy = 0x0040, // BUSY
1.218 + Cdc_do_not_expect_busy = 0x0000,
1.219 +
1.220 + Cdc_stream_block = 0x0020, // STREAM_BLOCK
1.221 + Cdc_not_stream_block = 0x0000,
1.222 +
1.223 + Cdc_write_operation = 0x0010, // WRITE_READ
1.224 + Cdc_read_operation = 0x0000,
1.225 +
1.226 + Cdc_data_with_command = 0x0008, // DATA_EN
1.227 + Cdc_no_data_with_command = 0x0000,
1.228 +
1.229 + Cdc_response_format_field_mask = 0x7, // RESPONSE_FORMAT
1.230 + Cdc_response_format_field_shift = 0,
1.231 +};
1.232 +
1.233 +enum Response_timeout_bits : unsigned
1.234 +{
1.235 + // NOTE: 16-bit value in the JZ4780.
1.236 + // NOTE: 32-bit value in the X1600.
1.237 +
1.238 + Response_timeout_mask = 0x000000ff, // RES_TO
1.239 +};
1.240 +
1.241 +enum Read_timeout_bits : unsigned
1.242 +{
1.243 + // NOTE: 16-bit value prior to the JZ4780/X1600.
1.244 +
1.245 + Read_timeout_mask = 0xffffffff, // READ_TO
1.246 +};
1.247 +
1.248 +enum Block_length_bits : unsigned
1.249 +{
1.250 + // NOTE: 16-bit value in the JZ4780/X1600.
1.251 +
1.252 + Block_length_mask = 0x00000fff, // BLK_LEN
1.253 +};
1.254 +
1.255 +enum Block_count_bits : unsigned
1.256 +{
1.257 + Block_count_mask = 0x0000ffff, // NOB/SNOB
1.258 +};
1.259 +
1.260 +// Interrupt mask/flag bits.
1.261 +
1.262 +enum Interrupt_bits : unsigned
1.263 +{
1.264 + // X1600 only.
1.265 +
1.266 + Int_dma_data_done = 0x80000000, // DMA_DATA_DONE
1.267 +
1.268 + // JZ4780 only.
1.269 +
1.270 + Int_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE
1.271 + Int_signal_voltage_change = 0x20000000, // SVS
1.272 +
1.273 + // JZ4780/X1600 only.
1.274 +
1.275 + Int_pin_level_field_mask = 0x1f, // PIN_LEVEL
1.276 + Int_pin_level_field_shift = 24,
1.277 +
1.278 + // X1600 only.
1.279 +
1.280 + Int_write_request_all_done = 0x00800000, // WR_ALL_DONE
1.281 +
1.282 + // JZ4780/X1600 only.
1.283 +
1.284 + Int_boot_crc_error = 0x00100000, // BCE
1.285 + Int_boot_data_end = 0x00080000, // BDE
1.286 + Int_boot_ack_error = 0x00040000, // BAE
1.287 + Int_boot_ack_received = 0x00020000, // BAR
1.288 + Int_dma_end = 0x00010000, // DMAEND
1.289 + Int_auto_cmd12_done = 0x00008000, // AUTO_CMD12_DONE
1.290 + Int_data_fifo_full = 0x00004000, // DATA_FIFO_FULL
1.291 + Int_data_fifo_empty = 0x00002000, // DATA_FIFO_EMP
1.292 + Int_crc_response_error = 0x00001000, // CRC_RES_ERR
1.293 + Int_crc_read_error = 0x00000800, // CRC_READ_ERR
1.294 + Int_crc_write_error = 0x00000400, // CRC_WRITE_ERR
1.295 + Int_response_timeout = 0x00000200, // TIME_OUT_RES
1.296 + Int_read_timeout = 0x00000100, // TIME_OUT_READ
1.297 +
1.298 + // Common.
1.299 +
1.300 + Int_sdio = 0x80, // SDIO
1.301 + Int_trans_fifo_write_request = 0x40, // TXFIFO_WR_REQ
1.302 + Int_recv_fifo_read_request = 0x20, // RXFIFO_RD_REQ
1.303 + Int_end_command_response = 0x04, // END_CMD_RES
1.304 + Int_programming_done = 0x02, // PRG_DONE
1.305 + Int_data_transfer_done = 0x01, // DATA_TRAN_DONE
1.306 +};
1.307 +
1.308 +enum Command_index_bits : unsigned
1.309 +{
1.310 + Command_index_mask = 0x0000003f, // CMD_INDEX
1.311 +};
1.312 +
1.313 +enum Command_argument_bits : unsigned
1.314 +{
1.315 + Command_argument_mask = 0xffffffff, // ARG
1.316 +};
1.317 +
1.318 +enum Response_fifo_bits : unsigned
1.319 +{
1.320 + Response_fifo_mask = 0x0000ffff, // DATA
1.321 +};
1.322 +
1.323 +enum Recv_data_fifo_bits : unsigned
1.324 +{
1.325 + Recv_data_fifo_mask = 0xffffffff, // DATA
1.326 +};
1.327 +
1.328 +enum Trans_data_fifo_bits : unsigned
1.329 +{
1.330 + Trans_data_fifo_mask = 0xffffffff, // DATA
1.331 +};
1.332 +
1.333 +enum Low_power_mode_bits : unsigned
1.334 +{
1.335 + Low_power_mode_enable = 0x00000001, // LPM
1.336 +};
1.337 +
1.338 +enum Dma_control_bits : unsigned
1.339 +{
1.340 + Dma_mode_specify_transfer_length = 0x80, // MODE_SEL
1.341 +
1.342 + Dma_address_offset_field_mask = 0x3, // AOFST
1.343 + Dma_address_offset_field_shift = 5,
1.344 +
1.345 + Dma_align_enable = 0x10, // ALIGNEN
1.346 +
1.347 + Dma_burst_type_field_mask = 0x3, // INCR
1.348 + Dma_burst_type_incr16 = 0,
1.349 + Dma_burst_type_incr32 = 1,
1.350 + Dma_burst_type_incr64 = 2,
1.351 + Dma_burst_type_field_shift = 2,
1.352 +
1.353 + Dma_select_common_dma = 0x02, // DMASEL
1.354 + Dma_select_special_dma = 0x00,
1.355 +
1.356 + Dma_enable = 0x01, // DMAEN
1.357 + Dma_disable = 0x00,
1.358 +};
1.359 +
1.360 +
1.361 +
1.362 +// Command indexes.
1.363 +
1.364 +enum Command_index : unsigned
1.365 +{
1.366 + Command_go_idle_state = 0,
1.367 + Command_send_op_cond = 1,
1.368 + Command_all_send_cid = 2,
1.369 + Command_send_relative_addr = 3, // SD
1.370 + Command_set_relative_addr = 3, // MMC
1.371 + Command_set_dsr = 4,
1.372 + Command_io_send_op_cond = 5, // SDIO
1.373 + Command_select_deselect_card = 7,
1.374 + Command_send_if_cond = 8,
1.375 + Command_send_csd = 9,
1.376 + Command_send_cid = 10,
1.377 + Command_read_dat_until_stop = 11,
1.378 + Command_stop_transmission = 12,
1.379 + Command_send_status = 13,
1.380 + Command_go_inactive_state = 15,
1.381 + Command_set_blocklen = 16,
1.382 + Command_read_single_block = 17,
1.383 + Command_read_multiple_block = 18,
1.384 + Command_write_dat_until_stop = 20,
1.385 + Command_set_block_count = 23,
1.386 + Command_write_block = 24,
1.387 + Command_write_multiple_block = 25,
1.388 + Command_program_cid = 26,
1.389 + Command_program_csd = 27,
1.390 + Command_set_write_prot = 28,
1.391 + Command_clr_write_prot = 29,
1.392 + Command_send_write_prot = 30,
1.393 + Command_tag_sector_start = 32,
1.394 + Command_tag_sector_end = 33,
1.395 + Command_untag_sector = 34,
1.396 + Command_tag_erase_group_start = 35,
1.397 + Command_tag_erase_group_end = 36,
1.398 + Command_untag_erase_group = 37,
1.399 + Command_erase = 38,
1.400 + Command_fast_io = 39,
1.401 + Command_go_irq_state = 40,
1.402 + Command_lock_unlock = 42,
1.403 + Command_io_rw_direct = 52, // SDIO
1.404 + Command_app_cmd = 55,
1.405 + Command_gen_cmd = 56,
1.406 +};
1.407 +
1.408 +// Application-specific command indexes, used by first issuing Command_app_cmd.
1.409 +
1.410 +enum App_command_index : unsigned
1.411 +{
1.412 + App_command_set_bus_width = 6,
1.413 + App_command_sd_status = 13,
1.414 + App_command_send_num_wr_blocks = 22,
1.415 + App_command_set_wr_block_erase_count = 23,
1.416 + App_command_sd_send_op_cond = 41,
1.417 + App_command_set_clr_card_detect = 42,
1.418 + App_command_send_scr = 51,
1.419 + App_command_read_ocr = 58,
1.420 +};
1.421 +
1.422 +enum Bus_width_bits : unsigned
1.423 +{
1.424 + Bus_width_1bit = 0,
1.425 + Bus_width_4bit = 2,
1.426 +};
1.427 +
1.428 +// Command response sizes in 16-bit units.
1.429 +
1.430 +enum Response_sizes : unsigned
1.431 +{
1.432 + Response_size_R1 = 3,
1.433 + Response_size_R2 = 8, // omits the CRC and end bit
1.434 + Response_size_R3 = 3,
1.435 + Response_size_R4 = 3,
1.436 + Response_size_R5 = 3,
1.437 + Response_size_R6 = 3,
1.438 + Response_size_R7 = 3,
1.439 +};
1.440 +
1.441 +// SD_SEND_OP_COND argument flags.
1.442 +
1.443 +enum Ocr_argument_flags : unsigned
1.444 +{
1.445 + Ocr_high_capacity_storage = 0x40000000,
1.446 +};
1.447 +
1.448 +// SD_SEND_OP_COND response flags (R3).
1.449 +
1.450 +enum Ocr_response_flags : unsigned
1.451 +{
1.452 + Ocr_card_powered_up = 0x80000000,
1.453 +};
1.454 +
1.455 +// R1 status flags.
1.456 +
1.457 +enum R1_status_flags : unsigned
1.458 +{
1.459 + R1_status_error_mask = 0xffff0000,
1.460 +};
1.461 +
1.462 +
1.463 +
1.464 +// MMC response structures.
1.465 +// These are 16-bit aligned to permit conversion to 16-bit arrays.
1.466 +
1.467 +struct R1
1.468 +{
1.469 + uint8_t end_crc;
1.470 + uint32_t status;
1.471 + uint8_t index:6, trans_start:2;
1.472 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.473 +
1.474 +struct R2
1.475 +{
1.476 + // uint8_t end_crc; (not retrieved)
1.477 +
1.478 + union
1.479 + {
1.480 + uint8_t raw[15];
1.481 + struct CID cid;
1.482 + struct CSD csd;
1.483 + } payload;
1.484 +
1.485 + uint8_t reserved_trans_start;
1.486 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.487 +
1.488 +struct R3
1.489 +{
1.490 + uint8_t end_reserved;
1.491 + uint32_t ocr;
1.492 + uint8_t reserved_trans_start;
1.493 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.494 +
1.495 +// SDIO response structures.
1.496 +
1.497 +struct R4
1.498 +{
1.499 + uint8_t end_reserved;
1.500 + uint32_t ocr:24, stuff:3, memory_present:1, number_io_functions:3, ready:1;
1.501 + uint8_t reserved_trans_start;
1.502 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.503 +
1.504 +struct R5
1.505 +{
1.506 + uint8_t end_crc;
1.507 + uint8_t data;
1.508 + uint8_t out_of_range:1, invalid_function_number:1, reserved:1, error:1,
1.509 + io_current_state:2, illegal_command:1, crc_error:1;
1.510 + uint16_t stuff;
1.511 + uint8_t index:6, trans_start:2;
1.512 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.513 +
1.514 +struct R6
1.515 +{
1.516 + uint8_t end_crc;
1.517 + uint16_t status;
1.518 + uint16_t rca;
1.519 + uint8_t index:6, trans_start:2;
1.520 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
1.521 +
1.522 +struct R7
1.523 +{
1.524 + uint8_t end_crc;
1.525 +
1.526 + union
1.527 + {
1.528 + uint32_t check:8, voltage:4, reserved:20;
1.529 + uint32_t raw;
1.530 + } check_voltage;
1.531 +
1.532 + uint8_t index:6, trans_start:2;
1.533 +} __attribute__((packed,aligned(__alignof__(uint16_t))));