1.1 --- a/pkg/devices/lib/msc/src/common.cc Sun Feb 18 22:43:39 2024 +0100
1.2 +++ b/pkg/devices/lib/msc/src/common.cc Sun Feb 18 22:45:07 2024 +0100
1.3 @@ -66,9 +66,9 @@
1.4 {
1.5 switch (width)
1.6 {
1.7 - case 4: return Cdc_bus_width_field_4bit;
1.8 - case 1: return Cdc_bus_width_field_1bit;
1.9 - default: return Cdc_bus_width_field_1bit;
1.10 + case 4: return Cdc_bus_width_4bit;
1.11 + case 1: return Cdc_bus_width_1bit;
1.12 + default: return Cdc_bus_width_1bit;
1.13 }
1.14 }
1.15
1.16 @@ -161,6 +161,18 @@
1.17 }
1.18
1.19 bool
1.20 +Msc_channel::have_dma_enable_in_command()
1.21 +{
1.22 + return false;
1.23 +}
1.24 +
1.25 +bool
1.26 +Msc_channel::have_dma_selection()
1.27 +{
1.28 + return true;
1.29 +}
1.30 +
1.31 +bool
1.32 Msc_channel::command_will_write(uint8_t index)
1.33 {
1.34 // NOTE: Probably incomplete coverage.
1.35 @@ -355,10 +367,11 @@
1.36 {
1.37 stop_clock();
1.38
1.39 - // Enable DMA for data transfers.
1.40 - // NOTE: Needed for JZ4780 and later SoCs.
1.41 + // Enable DMA for data transfers for JZ4780, X1600 and others that have a
1.42 + // channel-level control selecting special or conventional DMA.
1.43
1.44 - _regs[Msc_dma_control] = (data ? Dma_select_common_dma | Dma_enable : Dma_disable);
1.45 + if (have_dma_selection())
1.46 + _regs[Msc_dma_control] = (data ? Dma_select_common_dma | Dma_enable : Dma_disable);
1.47
1.48 // Set the command index and argument.
1.49
1.50 @@ -373,7 +386,8 @@
1.51 // NOTE: May need to set the SD bus width.
1.52
1.53 set_field(Msc_command_data_control, Cdc_bus_width_field_mask,
1.54 - Cdc_bus_width_field_shift, encode_bus_width(_cards[_card].bus_width));
1.55 + Cdc_bus_width_field_shift,
1.56 + encode_bus_width(_cards[_card].bus_width));
1.57
1.58 set_field(Msc_command_data_control, Cdc_recv_fifo_level_field_mask,
1.59 Cdc_recv_fifo_level_field_shift, Cdc_fifo_level_16);
1.60 @@ -382,22 +396,24 @@
1.61 Cdc_trans_fifo_level_field_shift, Cdc_fifo_level_16);
1.62
1.63 // Set and clear control bits appropriate to the command.
1.64 - // NOTE: Pre-JZ4780 SoCs enable DMA in this register.
1.65
1.66 _regs[Msc_command_data_control] = _regs[Msc_command_data_control] |
1.67 - // (data ? Cdc_dma_enable : Cdc_dma_disable) |
1.68 (busy ? Cdc_expect_busy : Cdc_do_not_expect_busy) |
1.69 (data ? Cdc_data_with_command : Cdc_no_data_with_command) |
1.70 (write ? Cdc_write_operation : Cdc_read_operation);
1.71
1.72 _regs[Msc_command_data_control] = _regs[Msc_command_data_control] &
1.73 - ~(
1.74 - // (data ? Cdc_dma_disable : Cdc_dma_enable) |
1.75 - (busy ? Cdc_do_not_expect_busy : Cdc_expect_busy) |
1.76 + ~((busy ? Cdc_do_not_expect_busy : Cdc_expect_busy) |
1.77 (data ? Cdc_no_data_with_command : Cdc_data_with_command) |
1.78 (write ? Cdc_read_operation : Cdc_write_operation) |
1.79 Cdc_stream_block | Cdc_init_sequence);
1.80
1.81 + // Pre-JZ4780 SoCs enable DMA in the command/data register.
1.82 +
1.83 + if (have_dma_enable_in_command())
1.84 + set_field(Msc_command_data_control, Cdc_dma_field_mask, Cdc_dma_field_shift,
1.85 + data ? Cdc_dma_enable : Cdc_dma_disable);
1.86 +
1.87 // Unmask interrupts, start the clock, then initiate the command.
1.88
1.89 uint32_t flags = Int_end_command_response | Int_response_timeout;