1.1 --- a/pkg/devices/lcd/include/lcd-device.h Fri Feb 16 23:11:25 2024 +0100 1.2 +++ b/pkg/devices/lcd/include/lcd-device.h Sat Feb 17 23:04:12 2024 +0100 1.3 @@ -1,7 +1,7 @@ 1.4 /* 1.5 * LCD device support. 1.6 * 1.7 - * Copyright (C) 2018, 2020, 2023 Paul Boddie <paul@boddie.org.uk> 1.8 + * Copyright (C) 2018, 2020, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 1.9 * 1.10 * This program is free software; you can redistribute it and/or 1.11 * modify it under the terms of the GNU General Public License as 1.12 @@ -21,6 +21,7 @@ 1.13 1.14 #pragma once 1.15 1.16 +#include <l4/devices/dma.h> 1.17 #include <l4/devices/lcd/activation_interface.h> 1.18 #include <l4/devices/lcd.h> 1.19 1.20 @@ -45,14 +46,10 @@ 1.21 1.22 Activation *_display; 1.23 1.24 - /* Framebuffer virtual and physical addresses. */ 1.25 + /* Framebuffer region providing virtual and physical addresses plus the memory 1.26 + capability for the framebuffer. */ 1.27 1.28 - l4_addr_t fb_vaddr; 1.29 - l4re_dma_space_dma_addr_t fb_paddr; 1.30 - 1.31 - /* Memory capability for the framebuffer. */ 1.32 - 1.33 - l4re_ds_t _fbmem; 1.34 + struct dma_region _fb_region; 1.35 1.36 /* Display operations. */ 1.37 1.38 @@ -66,18 +63,21 @@ 1.39 : _chip(chip), _display(display) 1.40 { 1.41 /* Subclasses must set up any memory. */ 1.42 + 1.43 + _fb_region.vaddr = 0; 1.44 + _fb_region.mem = L4_INVALID_CAP; 1.45 } 1.46 1.47 /* Framebuffer operations. */ 1.48 1.49 virtual l4_addr_t get_framebuffer() 1.50 { 1.51 - return fb_vaddr; 1.52 + return _fb_region.vaddr; 1.53 } 1.54 1.55 virtual l4re_ds_t get_framebuffer_cap() 1.56 { 1.57 - return _fbmem; 1.58 + return _fb_region.mem; 1.59 } 1.60 1.61 /* Querying operations. */
2.1 --- a/pkg/devices/lcd/include/lcd-jz4740-device.h Fri Feb 16 23:11:25 2024 +0100 2.2 +++ b/pkg/devices/lcd/include/lcd-jz4740-device.h Sat Feb 17 23:04:12 2024 +0100 2.3 @@ -1,7 +1,7 @@ 2.4 /* 2.5 * LCD device support for the JZ4740 and related SoCs. 2.6 * 2.7 - * Copyright (C) 2018, 2023 Paul Boddie <paul@boddie.org.uk> 2.8 + * Copyright (C) 2018, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 2.9 * 2.10 * This program is free software; you can redistribute it and/or 2.11 * modify it under the terms of the GNU General Public License as 2.12 @@ -38,10 +38,9 @@ 2.13 2.14 class Lcd_jz4740_device : public Lcd_device 2.15 { 2.16 - /* DMA descriptor virtual and physical addresses. */ 2.17 + /* DMA region providing the DMA descriptor virtual and physical addresses. */ 2.18 2.19 - l4_addr_t desc_vaddr; 2.20 - l4re_dma_space_dma_addr_t desc_paddr; 2.21 + struct dma_region _desc_region; 2.22 2.23 protected: 2.24 /* Device-specific memory allocation. */
3.1 --- a/pkg/devices/lcd/src/jz4740/lcd-jz4740-device.cc Fri Feb 16 23:11:25 2024 +0100 3.2 +++ b/pkg/devices/lcd/src/jz4740/lcd-jz4740-device.cc Sat Feb 17 23:04:12 2024 +0100 3.3 @@ -1,7 +1,7 @@ 3.4 /* 3.5 * Common LCD device support for the JZ4740 and related SoCs. 3.6 * 3.7 - * Copyright (C) 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 3.8 + * Copyright (C) 2018, 2020, 2021, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 3.9 * 3.10 * This program is free software; you can redistribute it and/or 3.11 * modify it under the terms of the GNU General Public License as 3.12 @@ -104,9 +104,9 @@ 3.13 // Configure the controller. 3.14 3.15 chip->disable(); 3.16 - chip->config((struct Jz4740_lcd_descriptor *) desc_vaddr, 3.17 - (struct Jz4740_lcd_descriptor *) desc_paddr, 3.18 - fb_paddr); 3.19 + chip->config((struct Jz4740_lcd_descriptor *) _desc_region.vaddr, 3.20 + (struct Jz4740_lcd_descriptor *) _desc_region.paddr, 3.21 + _fb_region.paddr); 3.22 3.23 // Activate the display channel. 3.24 3.25 @@ -125,7 +125,7 @@ 3.26 { 3.27 // Test for existing setup. 3.28 3.29 - if (fb_vaddr) 3.30 + if (_fb_region.vaddr) 3.31 return 0; 3.32 3.33 // Obtain the memory requirements. 3.34 @@ -140,14 +140,13 @@ 3.35 // Allocate memory for the framebuffer at 2**8 == 256 byte == 64 word 3.36 // alignment, with 2**6 == 64 byte == 16 word alignment for the descriptors. 3.37 3.38 - long err = get_dma_region(fb_size, 8, &fb_vaddr, &fb_paddr, &_fbmem); 3.39 + struct dma_region region; 3.40 + long err = get_dma_region(fb_size, 8, &_fb_region); 3.41 3.42 if (err) 3.43 return 1; 3.44 3.45 - l4_cap_idx_t descmem; 3.46 - 3.47 - err = get_dma_region(desc_size, 6, &desc_vaddr, &desc_paddr, &descmem); 3.48 + err = get_dma_region(desc_size, 6, &_desc_region); 3.49 3.50 if (err) 3.51 return 1;
4.1 --- a/pkg/devices/lib/msc/include/msc-common.h Fri Feb 16 23:11:25 2024 +0100 4.2 +++ b/pkg/devices/lib/msc/include/msc-common.h Sat Feb 17 23:04:12 2024 +0100 4.3 @@ -21,8 +21,10 @@ 4.4 4.5 #pragma once 4.6 4.7 +#include <l4/devices/clocks.h> 4.8 +#include <l4/devices/cpm.h> 4.9 +#include <l4/devices/dma.h> 4.10 #include <l4/devices/msc.h> 4.11 -#include <l4/re/c/dma_space.h> 4.12 #include <l4/sys/types.h> 4.13 #include <stdint.h> 4.14 4.15 @@ -42,6 +44,8 @@ 4.16 l4_addr_t _msc_start; 4.17 Hw::Register_block<32> _regs; 4.18 l4_cap_idx_t _irq; 4.19 + Cpm_chip *_cpm; 4.20 + enum Clock_identifiers _clock; 4.21 4.22 // Support eight cards. 4.23 4.24 @@ -58,7 +62,10 @@ 4.25 4.26 void ack_irq(uint32_t flags); 4.27 void unmask_irq(uint32_t flags); 4.28 - void reset(); 4.29 + 4.30 + virtual void reset(); 4.31 + 4.32 + bool set_clock_frequency(uint64_t frequency); 4.33 void start_clock(); 4.34 void stop_clock(); 4.35 4.36 @@ -99,15 +106,16 @@ 4.37 4.38 // Transfer operations. 4.39 4.40 - uint32_t recv_data(l4re_dma_space_dma_addr_t paddr, uint32_t count); 4.41 - uint32_t send_data(l4re_dma_space_dma_addr_t paddr, uint32_t count); 4.42 + uint32_t recv_data(struct dma_region *region, uint32_t count); 4.43 + uint32_t send_data(struct dma_region *region, uint32_t count); 4.44 4.45 virtual uint32_t transfer(l4re_dma_space_dma_addr_t from_paddr, 4.46 l4re_dma_space_dma_addr_t to_paddr, 4.47 bool recv, uint32_t count) = 0; 4.48 4.49 public: 4.50 - explicit Msc_channel(l4_addr_t msc_start, l4_addr_t start, l4_cap_idx_t irq); 4.51 + explicit Msc_channel(l4_addr_t msc_start, l4_addr_t start, l4_cap_idx_t irq, 4.52 + Cpm_chip *cpm, enum Clock_identifiers clock); 4.53 4.54 virtual ~Msc_channel(); 4.55 4.56 @@ -117,7 +125,7 @@ 4.57 4.58 uint8_t num_cards(); 4.59 4.60 - uint32_t read_blocks(uint8_t card, l4re_dma_space_dma_addr_t paddr, 4.61 + uint32_t read_blocks(uint8_t card, struct dma_region *region, 4.62 uint32_t block_address, uint32_t block_count); 4.63 }; 4.64 4.65 @@ -129,11 +137,13 @@ 4.66 { 4.67 protected: 4.68 l4_addr_t _msc_start, _start, _end; 4.69 + Cpm_chip *_cpm; 4.70 4.71 virtual unsigned int num_channels() = 0; 4.72 4.73 public: 4.74 - explicit Msc_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end); 4.75 + explicit Msc_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 4.76 + Cpm_chip *cpm); 4.77 }; 4.78 4.79 #endif /* __cplusplus */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/pkg/devices/lib/msc/include/msc-defs.h Sat Feb 17 23:04:12 2024 +0100 5.3 @@ -0,0 +1,530 @@ 5.4 +/* 5.5 + * MSC (MMC/SD controller) peripheral support. 5.6 + * 5.7 + * Copyright (C) 2024 Paul Boddie <paul@boddie.org.uk> 5.8 + * 5.9 + * This program is free software; you can redistribute it and/or 5.10 + * modify it under the terms of the GNU General Public License as 5.11 + * published by the Free Software Foundation; either version 2 of 5.12 + * the License, or (at your option) any later version. 5.13 + * 5.14 + * This program is distributed in the hope that it will be useful, 5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5.17 + * GNU General Public License for more details. 5.18 + * 5.19 + * You should have received a copy of the GNU General Public License 5.20 + * along with this program; if not, write to the Free Software 5.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 5.22 + * Boston, MA 02110-1301, USA 5.23 + */ 5.24 + 5.25 +#pragma once 5.26 + 5.27 +#include <l4/devices/msc-common.h> 5.28 + 5.29 + 5.30 + 5.31 +// Register locations for each channel. 5.32 + 5.33 +enum Regs : unsigned 5.34 +{ 5.35 + Msc_control = 0x000, // MSC_CTRL 5.36 + Msc_status = 0x004, // MSC_STAT 5.37 + Msc_clock_rate = 0x008, // MSC_CLKRT 5.38 + Msc_command_data_control = 0x00c, // MSC_CMDAT 5.39 + Msc_response_timeout = 0x010, // MSC_RESTO 5.40 + Msc_read_timeout = 0x014, // MSC_RDTO 5.41 + Msc_block_length = 0x018, // MSC_BLKLEN 5.42 + Msc_block_count = 0x01c, // MSC_NOB 5.43 + Msc_block_success_count = 0x020, // MSC_SNOB 5.44 + Msc_interrupt_mask = 0x024, // MSC_IMASK 5.45 + Msc_interrupt_flag = 0x028, // MSC_IFLG/MSC_IREG 5.46 + Msc_command_index = 0x02c, // MSC_CMD 5.47 + Msc_command_argument = 0x030, // MSC_ARG 5.48 + Msc_response_fifo = 0x034, // MSC_RES 5.49 + Msc_recv_data_fifo = 0x038, // MSC_RXFIFO 5.50 + Msc_trans_data_fifo = 0x03c, // MSC_TXFIFO 5.51 + 5.52 + // JZ4780/X1600 only. 5.53 + 5.54 + Msc_low_power_mode = 0x040, // MSC_LPM 5.55 + Msc_dma_control = 0x044, // MSC_DMAC 5.56 + Msc_dma_descriptor_address = 0x048, // MSC_DMANDA 5.57 + Msc_dma_data_address = 0x04c, // MSC_DMADA 5.58 + Msc_dma_data_length = 0x050, // MSC_DMALEN 5.59 + Msc_dma_command = 0x054, // MSC_DMACMD 5.60 + Msc_control2 = 0x058, // MSC_CTRL2 5.61 + Msc_rtfifo_data_counter = 0x05c, // MSC_RTCNT 5.62 + 5.63 + // Channel block size/offset. 5.64 + 5.65 + Msc_channel_offset = 0x10000, 5.66 +}; 5.67 + 5.68 +// Field definitions. 5.69 + 5.70 +enum Control_bits : unsigned 5.71 +{ 5.72 + // JZ4780/X1600 only. 5.73 + 5.74 + Control_send_ccsd = 0x8000, // SEND_CCSD 5.75 + Control_send_ccsd_automatically = 0x4000, // SEND_CCSD 5.76 + 5.77 + // Common. 5.78 + 5.79 + Control_exit_multiple = 0x0080, // EXIT_MULTIPLE 5.80 + Control_exit_transfer = 0x0040, // EXIT_TRANSFER 5.81 + Control_start_read_wait = 0x0020, // START_READ_WAIT 5.82 + Control_stop_read_wait = 0x0010, // STOP_READ_WAIT 5.83 + Control_reset = 0x0008, // RESET 5.84 + Control_start_operation = 0x0004, // START_OP 5.85 + 5.86 + Control_clock_control_field_mask = 0x3, // CLOCK_CTRL 5.87 + Control_clock_control_start = 2, 5.88 + Control_clock_control_stop = 1, 5.89 + Control_clock_control_field_shift = 0, 5.90 +}; 5.91 + 5.92 +enum Control2_bits : unsigned 5.93 +{ 5.94 + // JZ4780/X1600 only. 5.95 + 5.96 + Control2_pin_level_polarity_field_mask = 0x1f, // PIP 5.97 + Control2_pin_level_polarity_field_shift = 24, 5.98 + 5.99 + // JZ4780 only. 5.100 + 5.101 + Control2_reset_enable = 0x00800000, // RST_EN 5.102 + 5.103 + // JZ4780/X1600 only. 5.104 + 5.105 + Control2_stop_read_operation_mode = 0x00000010, // STPRM 5.106 + 5.107 + // JZ4780 only. 5.108 + 5.109 + Control2_signal_voltage_change = 0x00000008, // SVC 5.110 + 5.111 + // JZ4780/X1600 only. 5.112 + 5.113 + Control2_speed_mode_field_mask = 0x7, // SMS 5.114 + Control2_speed_mode_default = 0, // = 0 5.115 + Control2_speed_mode_high = 1, // = 1 5.116 + Control2_speed_mode_sdr12 = 2, // = 2 5.117 + Control2_speed_mode_sdr25 = 3, // = 3 5.118 + Control2_speed_mode_sdr50 = 4, // = 4 5.119 + Control2_speed_mode_field_shift = 0, 5.120 +}; 5.121 + 5.122 +enum Status_bits : unsigned 5.123 +{ 5.124 + // JZ4780/X1600 only. 5.125 + 5.126 + Status_auto_cmd12_done = 0x80000000, // AUTO_CMD12_DONE 5.127 + 5.128 + // JZ4780 only. 5.129 + 5.130 + Status_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE 5.131 + Status_signal_voltage_change = 0x20000000, // SVS 5.132 + 5.133 + // JZ4780/X1600 only. 5.134 + 5.135 + Status_pin_level_field_mask = 0x1f, // PIN_LEVEL 5.136 + Status_pin_level_field_shift = 24, 5.137 + 5.138 + Status_boot_crc_error = 0x00100000, // BCE 5.139 + Status_boot_data_end = 0x00080000, // BDE 5.140 + Status_boot_ack_error = 0x00040000, // BAE 5.141 + Status_boot_ack_received = 0x00020000, // BAR 5.142 + Status_dma_end = 0x00010000, // DMAEND 5.143 + 5.144 + // Common. 5.145 + 5.146 + Status_resetting = 0x8000, // IS_RESETTING 5.147 + Status_sdio_interrupt_active = 0x4000, // SDIO_INT_ACTIVE 5.148 + Status_programming_done = 0x2000, // PRG_DONE 5.149 + Status_data_transfer_done = 0x1000, // DATA_TRAN_DONE 5.150 + Status_end_command_response = 0x0800, // END_CMD_RES 5.151 + Status_data_fifo_almost_full = 0x0400, // DATA_FIFO_AFULL 5.152 + Status_read_wait = 0x0200, // IS_READWAIT 5.153 + Status_clock_enabled = 0x0100, // CLK_EN 5.154 + Status_data_fifo_full = 0x0080, // DATA_FIFO_FULL 5.155 + Status_data_fifo_empty = 0x0040, // DATA_FIFO_EMPTY 5.156 + Status_response_crc_error = 0x0020, // CRC_RES_ERR 5.157 + Status_read_crc_error = 0x0010, // CRC_READ_ERROR 5.158 + Status_write_crc_error_no_status = 0x0008, // CRC_WRITE_ERROR (2) 5.159 + Status_write_crc_error_data = 0x0004, // CRC_WRITE_ERROR (1) 5.160 + Status_timeout_response = 0x0002, // TIME_OUT_RES 5.161 + Status_timeout_read = 0x0001, // TIME_OUT_READ 5.162 +}; 5.163 + 5.164 +enum Clock_rate_bits : unsigned 5.165 +{ 5.166 + Clock_rate_field_mask = 0x7, // CLK_RATE 5.167 + Clock_rate_field_shift = 0, 5.168 +}; 5.169 + 5.170 +enum Command_data_control_bits : unsigned 5.171 +{ 5.172 + // JZ4780/X1600 only. 5.173 + 5.174 + Cdc_ccs_expected = 0x80000000, // CCS_EXPECTED 5.175 + Cdc_read_ce_ata = 0x40000000, // READ_CEATA 5.176 + Cdc_disable_boot = 0x08000000, // DIS_BOOT 5.177 + Cdc_expect_boot_ack = 0x02000000, // EXP_BOOT_ACK 5.178 + Cdc_alternative_boot_mode = 0x01000000, // BOOT_MODE 5.179 + 5.180 + // JZ4780 only. 5.181 + 5.182 + Cdc_auto_cmd23 = 0x00040000, // AUTO_CMD23 5.183 + 5.184 + // JZ4780/X1600 only. 5.185 + 5.186 + Cdc_sdio_interrupt_2cycle = 0x00020000, // SDIO_PRDT 5.187 + Cdc_auto_cmd12 = 0x00010000, // AUTO_CMD12 5.188 + 5.189 + Cdc_recv_fifo_level_field_mask = 0x3, // RTRG 5.190 + Cdc_fifo_level_16 = 0, 5.191 + Cdc_fifo_level_32 = 1, 5.192 + Cdc_fifo_level_64 = 2, 5.193 + Cdc_fifo_level_96 = 3, 5.194 + Cdc_recv_fifo_level_field_shift = 14, 5.195 + 5.196 + Cdc_trans_fifo_level_field_mask = 0x3, // TTRG 5.197 + Cdc_trans_fifo_level_field_shift = 12, 5.198 + 5.199 + // Common. 5.200 + 5.201 + Cdc_io_abort = 0x0800, // IO_ABORT 5.202 + 5.203 + Cdc_bus_width_field_mask = 0x3, // BUS_WIDTH 5.204 + Cdc_bus_width_field_1bit = 0, // = 0 5.205 + Cdc_bus_width_field_4bit = 2, // = 2 5.206 + Cdc_bus_width_field_shift = 9, 5.207 + 5.208 + // JZ4740 only. 5.209 + 5.210 + Cdc_dma_enable = 0x0100, // DMA_EN 5.211 + Cdc_dma_disable = 0x0000, 5.212 + 5.213 + // Common. 5.214 + 5.215 + Cdc_init_sequence = 0x0080, // INIT 5.216 + 5.217 + Cdc_expect_busy = 0x0040, // BUSY 5.218 + Cdc_do_not_expect_busy = 0x0000, 5.219 + 5.220 + Cdc_stream_block = 0x0020, // STREAM_BLOCK 5.221 + Cdc_not_stream_block = 0x0000, 5.222 + 5.223 + Cdc_write_operation = 0x0010, // WRITE_READ 5.224 + Cdc_read_operation = 0x0000, 5.225 + 5.226 + Cdc_data_with_command = 0x0008, // DATA_EN 5.227 + Cdc_no_data_with_command = 0x0000, 5.228 + 5.229 + Cdc_response_format_field_mask = 0x7, // RESPONSE_FORMAT 5.230 + Cdc_response_format_field_shift = 0, 5.231 +}; 5.232 + 5.233 +enum Response_timeout_bits : unsigned 5.234 +{ 5.235 + // NOTE: 16-bit value in the JZ4780. 5.236 + // NOTE: 32-bit value in the X1600. 5.237 + 5.238 + Response_timeout_mask = 0x000000ff, // RES_TO 5.239 +}; 5.240 + 5.241 +enum Read_timeout_bits : unsigned 5.242 +{ 5.243 + // NOTE: 16-bit value prior to the JZ4780/X1600. 5.244 + 5.245 + Read_timeout_mask = 0xffffffff, // READ_TO 5.246 +}; 5.247 + 5.248 +enum Block_length_bits : unsigned 5.249 +{ 5.250 + // NOTE: 16-bit value in the JZ4780/X1600. 5.251 + 5.252 + Block_length_mask = 0x00000fff, // BLK_LEN 5.253 +}; 5.254 + 5.255 +enum Block_count_bits : unsigned 5.256 +{ 5.257 + Block_count_mask = 0x0000ffff, // NOB/SNOB 5.258 +}; 5.259 + 5.260 +// Interrupt mask/flag bits. 5.261 + 5.262 +enum Interrupt_bits : unsigned 5.263 +{ 5.264 + // X1600 only. 5.265 + 5.266 + Int_dma_data_done = 0x80000000, // DMA_DATA_DONE 5.267 + 5.268 + // JZ4780 only. 5.269 + 5.270 + Int_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE 5.271 + Int_signal_voltage_change = 0x20000000, // SVS 5.272 + 5.273 + // JZ4780/X1600 only. 5.274 + 5.275 + Int_pin_level_field_mask = 0x1f, // PIN_LEVEL 5.276 + Int_pin_level_field_shift = 24, 5.277 + 5.278 + // X1600 only. 5.279 + 5.280 + Int_write_request_all_done = 0x00800000, // WR_ALL_DONE 5.281 + 5.282 + // JZ4780/X1600 only. 5.283 + 5.284 + Int_boot_crc_error = 0x00100000, // BCE 5.285 + Int_boot_data_end = 0x00080000, // BDE 5.286 + Int_boot_ack_error = 0x00040000, // BAE 5.287 + Int_boot_ack_received = 0x00020000, // BAR 5.288 + Int_dma_end = 0x00010000, // DMAEND 5.289 + Int_auto_cmd12_done = 0x00008000, // AUTO_CMD12_DONE 5.290 + Int_data_fifo_full = 0x00004000, // DATA_FIFO_FULL 5.291 + Int_data_fifo_empty = 0x00002000, // DATA_FIFO_EMP 5.292 + Int_crc_response_error = 0x00001000, // CRC_RES_ERR 5.293 + Int_crc_read_error = 0x00000800, // CRC_READ_ERR 5.294 + Int_crc_write_error = 0x00000400, // CRC_WRITE_ERR 5.295 + Int_response_timeout = 0x00000200, // TIME_OUT_RES 5.296 + Int_read_timeout = 0x00000100, // TIME_OUT_READ 5.297 + 5.298 + // Common. 5.299 + 5.300 + Int_sdio = 0x80, // SDIO 5.301 + Int_trans_fifo_write_request = 0x40, // TXFIFO_WR_REQ 5.302 + Int_recv_fifo_read_request = 0x20, // RXFIFO_RD_REQ 5.303 + Int_end_command_response = 0x04, // END_CMD_RES 5.304 + Int_programming_done = 0x02, // PRG_DONE 5.305 + Int_data_transfer_done = 0x01, // DATA_TRAN_DONE 5.306 +}; 5.307 + 5.308 +enum Command_index_bits : unsigned 5.309 +{ 5.310 + Command_index_mask = 0x0000003f, // CMD_INDEX 5.311 +}; 5.312 + 5.313 +enum Command_argument_bits : unsigned 5.314 +{ 5.315 + Command_argument_mask = 0xffffffff, // ARG 5.316 +}; 5.317 + 5.318 +enum Response_fifo_bits : unsigned 5.319 +{ 5.320 + Response_fifo_mask = 0x0000ffff, // DATA 5.321 +}; 5.322 + 5.323 +enum Recv_data_fifo_bits : unsigned 5.324 +{ 5.325 + Recv_data_fifo_mask = 0xffffffff, // DATA 5.326 +}; 5.327 + 5.328 +enum Trans_data_fifo_bits : unsigned 5.329 +{ 5.330 + Trans_data_fifo_mask = 0xffffffff, // DATA 5.331 +}; 5.332 + 5.333 +enum Low_power_mode_bits : unsigned 5.334 +{ 5.335 + Low_power_mode_enable = 0x00000001, // LPM 5.336 +}; 5.337 + 5.338 +enum Dma_control_bits : unsigned 5.339 +{ 5.340 + Dma_mode_specify_transfer_length = 0x80, // MODE_SEL 5.341 + 5.342 + Dma_address_offset_field_mask = 0x3, // AOFST 5.343 + Dma_address_offset_field_shift = 5, 5.344 + 5.345 + Dma_align_enable = 0x10, // ALIGNEN 5.346 + 5.347 + Dma_burst_type_field_mask = 0x3, // INCR 5.348 + Dma_burst_type_incr16 = 0, 5.349 + Dma_burst_type_incr32 = 1, 5.350 + Dma_burst_type_incr64 = 2, 5.351 + Dma_burst_type_field_shift = 2, 5.352 + 5.353 + Dma_select_common_dma = 0x02, // DMASEL 5.354 + Dma_select_special_dma = 0x00, 5.355 + 5.356 + Dma_enable = 0x01, // DMAEN 5.357 + Dma_disable = 0x00, 5.358 +}; 5.359 + 5.360 + 5.361 + 5.362 +// Command indexes. 5.363 + 5.364 +enum Command_index : unsigned 5.365 +{ 5.366 + Command_go_idle_state = 0, 5.367 + Command_send_op_cond = 1, 5.368 + Command_all_send_cid = 2, 5.369 + Command_send_relative_addr = 3, // SD 5.370 + Command_set_relative_addr = 3, // MMC 5.371 + Command_set_dsr = 4, 5.372 + Command_io_send_op_cond = 5, // SDIO 5.373 + Command_select_deselect_card = 7, 5.374 + Command_send_if_cond = 8, 5.375 + Command_send_csd = 9, 5.376 + Command_send_cid = 10, 5.377 + Command_read_dat_until_stop = 11, 5.378 + Command_stop_transmission = 12, 5.379 + Command_send_status = 13, 5.380 + Command_go_inactive_state = 15, 5.381 + Command_set_blocklen = 16, 5.382 + Command_read_single_block = 17, 5.383 + Command_read_multiple_block = 18, 5.384 + Command_write_dat_until_stop = 20, 5.385 + Command_set_block_count = 23, 5.386 + Command_write_block = 24, 5.387 + Command_write_multiple_block = 25, 5.388 + Command_program_cid = 26, 5.389 + Command_program_csd = 27, 5.390 + Command_set_write_prot = 28, 5.391 + Command_clr_write_prot = 29, 5.392 + Command_send_write_prot = 30, 5.393 + Command_tag_sector_start = 32, 5.394 + Command_tag_sector_end = 33, 5.395 + Command_untag_sector = 34, 5.396 + Command_tag_erase_group_start = 35, 5.397 + Command_tag_erase_group_end = 36, 5.398 + Command_untag_erase_group = 37, 5.399 + Command_erase = 38, 5.400 + Command_fast_io = 39, 5.401 + Command_go_irq_state = 40, 5.402 + Command_lock_unlock = 42, 5.403 + Command_io_rw_direct = 52, // SDIO 5.404 + Command_app_cmd = 55, 5.405 + Command_gen_cmd = 56, 5.406 +}; 5.407 + 5.408 +// Application-specific command indexes, used by first issuing Command_app_cmd. 5.409 + 5.410 +enum App_command_index : unsigned 5.411 +{ 5.412 + App_command_set_bus_width = 6, 5.413 + App_command_sd_status = 13, 5.414 + App_command_send_num_wr_blocks = 22, 5.415 + App_command_set_wr_block_erase_count = 23, 5.416 + App_command_sd_send_op_cond = 41, 5.417 + App_command_set_clr_card_detect = 42, 5.418 + App_command_send_scr = 51, 5.419 + App_command_read_ocr = 58, 5.420 +}; 5.421 + 5.422 +enum Bus_width_bits : unsigned 5.423 +{ 5.424 + Bus_width_1bit = 0, 5.425 + Bus_width_4bit = 2, 5.426 +}; 5.427 + 5.428 +// Command response sizes in 16-bit units. 5.429 + 5.430 +enum Response_sizes : unsigned 5.431 +{ 5.432 + Response_size_R1 = 3, 5.433 + Response_size_R2 = 8, // omits the CRC and end bit 5.434 + Response_size_R3 = 3, 5.435 + Response_size_R4 = 3, 5.436 + Response_size_R5 = 3, 5.437 + Response_size_R6 = 3, 5.438 + Response_size_R7 = 3, 5.439 +}; 5.440 + 5.441 +// SD_SEND_OP_COND argument flags. 5.442 + 5.443 +enum Ocr_argument_flags : unsigned 5.444 +{ 5.445 + Ocr_high_capacity_storage = 0x40000000, 5.446 +}; 5.447 + 5.448 +// SD_SEND_OP_COND response flags (R3). 5.449 + 5.450 +enum Ocr_response_flags : unsigned 5.451 +{ 5.452 + Ocr_card_powered_up = 0x80000000, 5.453 +}; 5.454 + 5.455 +// R1 status flags. 5.456 + 5.457 +enum R1_status_flags : unsigned 5.458 +{ 5.459 + R1_status_error_mask = 0xffff0000, 5.460 +}; 5.461 + 5.462 + 5.463 + 5.464 +// MMC response structures. 5.465 +// These are 16-bit aligned to permit conversion to 16-bit arrays. 5.466 + 5.467 +struct R1 5.468 +{ 5.469 + uint8_t end_crc; 5.470 + uint32_t status; 5.471 + uint8_t index:6, trans_start:2; 5.472 +} __attribute__((packed,aligned(__alignof__(uint16_t)))); 5.473 + 5.474 +struct R2 5.475 +{ 5.476 + // uint8_t end_crc; (not retrieved) 5.477 + 5.478 + union 5.479 + { 5.480 + uint8_t raw[15]; 5.481 + struct CID cid; 5.482 + struct CSD csd; 5.483 + } payload; 5.484 + 5.485 + uint8_t reserved_trans_start; 5.486 +} __attribute__((packed,aligned(__alignof__(uint16_t)))); 5.487 + 5.488 +struct R3 5.489 +{ 5.490 + uint8_t end_reserved; 5.491 + uint32_t ocr; 5.492 + uint8_t reserved_trans_start; 5.493 +} __attribute__((packed,aligned(__alignof__(uint16_t)))); 5.494 + 5.495 +// SDIO response structures. 5.496 + 5.497 +struct R4 5.498 +{ 5.499 + uint8_t end_reserved; 5.500 + uint32_t ocr:24, stuff:3, memory_present:1, number_io_functions:3, ready:1; 5.501 + uint8_t reserved_trans_start; 5.502 +} __attribute__((packed,aligned(__alignof__(uint16_t)))); 5.503 + 5.504 +struct R5 5.505 +{ 5.506 + uint8_t end_crc; 5.507 + uint8_t data; 5.508 + uint8_t out_of_range:1, invalid_function_number:1, reserved:1, error:1, 5.509 + io_current_state:2, illegal_command:1, crc_error:1; 5.510 + uint16_t stuff; 5.511 + uint8_t index:6, trans_start:2; 5.512 +} __attribute__((packed,aligned(__alignof__(uint16_t)))); 5.513 + 5.514 +struct R6 5.515 +{ 5.516 + uint8_t end_crc; 5.517 + uint16_t status; 5.518 + uint16_t rca; 5.519 + uint8_t index:6, trans_start:2; 5.520 +} __attribute__((packed,aligned(__alignof__(uint16_t)))); 5.521 + 5.522 +struct R7 5.523 +{ 5.524 + uint8_t end_crc; 5.525 + 5.526 + union 5.527 + { 5.528 + uint32_t check:8, voltage:4, reserved:20; 5.529 + uint32_t raw; 5.530 + } check_voltage; 5.531 + 5.532 + uint8_t index:6, trans_start:2; 5.533 +} __attribute__((packed,aligned(__alignof__(uint16_t))));
6.1 --- a/pkg/devices/lib/msc/include/msc-jz4780.h Fri Feb 16 23:11:25 2024 +0100 6.2 +++ b/pkg/devices/lib/msc/include/msc-jz4780.h Sat Feb 17 23:04:12 2024 +0100 6.3 @@ -22,7 +22,6 @@ 6.4 #pragma once 6.5 6.6 #include <l4/devices/msc-common.h> 6.7 -#include <l4/re/c/dma_space.h> 6.8 #include <l4/sys/types.h> 6.9 #include <stdint.h> 6.10 6.11 @@ -42,7 +41,9 @@ 6.12 6.13 public: 6.14 explicit Msc_jz4780_channel(l4_addr_t msc_start, l4_addr_t addr, 6.15 - l4_cap_idx_t irq, Dma_jz4780_channel *dma, 6.16 + l4_cap_idx_t irq, Cpm_chip *cpm, 6.17 + enum Clock_identifiers clock, 6.18 + Dma_jz4780_channel *dma, 6.19 enum Dma_jz4780_request_type request_type_in, 6.20 enum Dma_jz4780_request_type request_type_out); 6.21 6.22 @@ -57,12 +58,22 @@ 6.23 6.24 class Msc_jz4780_chip : public Msc_chip 6.25 { 6.26 -protected: 6.27 +protected: 6.28 + const enum Dma_jz4780_request_type _in_types[3] = 6.29 + {Dma_request_msc0_in, Dma_request_msc1_in, Dma_request_msc2_in}; 6.30 + 6.31 + const enum Dma_jz4780_request_type _out_types[3] = 6.32 + {Dma_request_msc0_out, Dma_request_msc1_out, Dma_request_msc2_out}; 6.33 + 6.34 + const enum Clock_identifiers _clocks[3] = 6.35 + {Clock_msc0, Clock_msc1, Clock_msc2}; 6.36 + 6.37 unsigned int num_channels() 6.38 { return 3; } 6.39 6.40 public: 6.41 - explicit Msc_jz4780_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end); 6.42 + explicit Msc_jz4780_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 6.43 + Cpm_chip *cpm); 6.44 6.45 Msc_channel *get_channel(uint8_t channel, l4_cap_idx_t irq, 6.46 Dma_jz4780_channel *dma); 6.47 @@ -74,7 +85,8 @@ 6.48 6.49 EXTERN_C_BEGIN 6.50 6.51 -void *jz4780_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end); 6.52 +void *jz4780_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 6.53 + void *cpm); 6.54 6.55 void *jz4780_msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, 6.56 void *dma); 6.57 @@ -86,7 +98,7 @@ 6.58 void jz4780_msc_enable(void *msc_channel); 6.59 6.60 uint32_t jz4780_msc_read_blocks(void *msc_channel, uint8_t card, 6.61 - l4re_dma_space_dma_addr_t paddr, 6.62 + struct dma_region *region, 6.63 uint32_t block_address, uint32_t block_count); 6.64 6.65 EXTERN_C_END
7.1 --- a/pkg/devices/lib/msc/include/msc-x1600.h Fri Feb 16 23:11:25 2024 +0100 7.2 +++ b/pkg/devices/lib/msc/include/msc-x1600.h Sat Feb 17 23:04:12 2024 +0100 7.3 @@ -22,7 +22,6 @@ 7.4 #pragma once 7.5 7.6 #include <l4/devices/msc-common.h> 7.7 -#include <l4/re/c/dma_space.h> 7.8 #include <l4/sys/types.h> 7.9 #include <stdint.h> 7.10 7.11 @@ -40,9 +39,15 @@ 7.12 Dma_x1600_channel *_dma; 7.13 enum Dma_x1600_request_type _request_type_in, _request_type_out; 7.14 7.15 + // Special overridden method. 7.16 + 7.17 + void reset(); 7.18 + 7.19 public: 7.20 explicit Msc_x1600_channel(l4_addr_t msc_start, l4_addr_t addr, 7.21 - l4_cap_idx_t irq, Dma_x1600_channel *dma, 7.22 + l4_cap_idx_t irq, Cpm_chip *cpm, 7.23 + enum Clock_identifiers clock, 7.24 + Dma_x1600_channel *dma, 7.25 enum Dma_x1600_request_type request_type_in, 7.26 enum Dma_x1600_request_type request_type_out); 7.27 7.28 @@ -55,12 +60,22 @@ 7.29 7.30 class Msc_x1600_chip : public Msc_chip 7.31 { 7.32 -protected: 7.33 +protected: 7.34 + const enum Dma_x1600_request_type _in_types[2] = 7.35 + {Dma_request_msc0_in, Dma_request_msc1_in}; 7.36 + 7.37 + const enum Dma_x1600_request_type _out_types[2] = 7.38 + {Dma_request_msc0_out, Dma_request_msc1_out}; 7.39 + 7.40 + const enum Clock_identifiers _clocks[2] = 7.41 + {Clock_msc0, Clock_msc1}; 7.42 + 7.43 unsigned int num_channels() 7.44 { return 2; } 7.45 7.46 public: 7.47 - explicit Msc_x1600_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end); 7.48 + explicit Msc_x1600_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 7.49 + Cpm_chip *cpm); 7.50 7.51 Msc_channel *get_channel(uint8_t channel, l4_cap_idx_t irq, 7.52 Dma_x1600_channel *dma); 7.53 @@ -72,7 +87,8 @@ 7.54 7.55 EXTERN_C_BEGIN 7.56 7.57 -void *x1600_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end); 7.58 +void *x1600_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 7.59 + void *cpm); 7.60 7.61 void *x1600_msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, 7.62 void *dma); 7.63 @@ -84,7 +100,7 @@ 7.64 void x1600_msc_enable(void *msc_channel); 7.65 7.66 uint32_t x1600_msc_read_blocks(void *msc_channel, uint8_t card, 7.67 - l4re_dma_space_dma_addr_t paddr, 7.68 + struct dma_region *region, 7.69 uint32_t block_address, uint32_t block_count); 7.70 7.71 EXTERN_C_END
8.1 --- a/pkg/devices/lib/msc/src/common.cc Fri Feb 16 23:11:25 2024 +0100 8.2 +++ b/pkg/devices/lib/msc/src/common.cc Sat Feb 17 23:04:12 2024 +0100 8.3 @@ -23,515 +23,11 @@ 8.4 #include <l4/sys/irq.h> 8.5 #include <l4/util/util.h> 8.6 8.7 +#include <math.h> 8.8 #include <stdio.h> 8.9 8.10 #include "msc-common.h" 8.11 - 8.12 - 8.13 - 8.14 -// Register locations for each channel. 8.15 - 8.16 -enum Regs : unsigned 8.17 -{ 8.18 - Msc_control = 0x000, // MSC_CTRL 8.19 - Msc_status = 0x004, // MSC_STAT 8.20 - Msc_clock_rate = 0x008, // MSC_CLKRT 8.21 - Msc_command_data_control = 0x00c, // MSC_CMDAT 8.22 - Msc_response_timeout = 0x010, // MSC_RESTO 8.23 - Msc_read_timeout = 0x014, // MSC_RDTO 8.24 - Msc_block_length = 0x018, // MSC_BLKLEN 8.25 - Msc_block_count = 0x01c, // MSC_NOB 8.26 - Msc_block_success_count = 0x020, // MSC_SNOB 8.27 - Msc_interrupt_mask = 0x024, // MSC_IMASK 8.28 - Msc_interrupt_flag = 0x028, // MSC_IFLG/MSC_IREG 8.29 - Msc_command_index = 0x02c, // MSC_CMD 8.30 - Msc_command_argument = 0x030, // MSC_ARG 8.31 - Msc_response_fifo = 0x034, // MSC_RES 8.32 - Msc_recv_data_fifo = 0x038, // MSC_RXFIFO 8.33 - Msc_trans_data_fifo = 0x03c, // MSC_TXFIFO 8.34 - 8.35 - // JZ4780/X1600 only. 8.36 - 8.37 - Msc_low_power_mode = 0x040, // MSC_LPM 8.38 - Msc_dma_control = 0x044, // MSC_DMAC 8.39 - Msc_dma_descriptor_address = 0x048, // MSC_DMANDA 8.40 - Msc_dma_data_address = 0x04c, // MSC_DMADA 8.41 - Msc_dma_data_length = 0x050, // MSC_DMALEN 8.42 - Msc_dma_command = 0x054, // MSC_DMACMD 8.43 - Msc_control2 = 0x058, // MSC_CTRL2 8.44 - Msc_rtfifo_data_counter = 0x05c, // MSC_RTCNT 8.45 - 8.46 - // Channel block size/offset. 8.47 - 8.48 - Msc_channel_offset = 0x10000, 8.49 -}; 8.50 - 8.51 -// Field definitions. 8.52 - 8.53 -enum Control_bits : unsigned 8.54 -{ 8.55 - // JZ4780/X1600 only. 8.56 - 8.57 - Control_send_ccsd = 0x8000, // SEND_CCSD 8.58 - Control_send_ccsd_automatically = 0x4000, // SEND_CCSD 8.59 - 8.60 - // Common. 8.61 - 8.62 - Control_exit_multiple = 0x0080, // EXIT_MULTIPLE 8.63 - Control_exit_transfer = 0x0040, // EXIT_TRANSFER 8.64 - Control_start_read_wait = 0x0020, // START_READ_WAIT 8.65 - Control_stop_read_wait = 0x0010, // STOP_READ_WAIT 8.66 - Control_reset = 0x0008, // RESET 8.67 - Control_start_operation = 0x0004, // START_OP 8.68 - 8.69 - Control_clock_control_field_mask = 0x3, // CLOCK_CTRL 8.70 - Control_clock_control_start = 2, 8.71 - Control_clock_control_stop = 1, 8.72 - Control_clock_control_field_shift = 0, 8.73 -}; 8.74 - 8.75 -enum Control2_bits : unsigned 8.76 -{ 8.77 - // JZ4780/X1600 only. 8.78 - 8.79 - Control2_pin_level_polarity_field_mask = 0x1f, // PIP 8.80 - Control2_pin_level_polarity_field_shift = 24, 8.81 - 8.82 - // JZ4780 only. 8.83 - 8.84 - Control2_reset_enable = 0x00800000, // RST_EN 8.85 - 8.86 - // JZ4780/X1600 only. 8.87 - 8.88 - Control2_stop_read_operation_mode = 0x00000010, // STPRM 8.89 - 8.90 - // JZ4780 only. 8.91 - 8.92 - Control2_signal_voltage_change = 0x00000008, // SVC 8.93 - 8.94 - // JZ4780/X1600 only. 8.95 - 8.96 - Control2_speed_mode_field_mask = 0x7, // SMS 8.97 - Control2_speed_mode_default = 0, // = 0 8.98 - Control2_speed_mode_high = 1, // = 1 8.99 - Control2_speed_mode_sdr12 = 2, // = 2 8.100 - Control2_speed_mode_sdr25 = 3, // = 3 8.101 - Control2_speed_mode_sdr50 = 4, // = 4 8.102 - Control2_speed_mode_field_shift = 0, 8.103 -}; 8.104 - 8.105 -enum Status_bits : unsigned 8.106 -{ 8.107 - // JZ4780/X1600 only. 8.108 - 8.109 - Status_auto_cmd12_done = 0x80000000, // AUTO_CMD12_DONE 8.110 - 8.111 - // JZ4780 only. 8.112 - 8.113 - Status_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE 8.114 - Status_signal_voltage_change = 0x20000000, // SVS 8.115 - 8.116 - // JZ4780/X1600 only. 8.117 - 8.118 - Status_pin_level_field_mask = 0x1f, // PIN_LEVEL 8.119 - Status_pin_level_field_shift = 24, 8.120 - 8.121 - Status_boot_crc_error = 0x00100000, // BCE 8.122 - Status_boot_data_end = 0x00080000, // BDE 8.123 - Status_boot_ack_error = 0x00040000, // BAE 8.124 - Status_boot_ack_received = 0x00020000, // BAR 8.125 - Status_dma_end = 0x00010000, // DMAEND 8.126 - 8.127 - // Common. 8.128 - 8.129 - Status_resetting = 0x8000, // IS_RESETTING 8.130 - Status_sdio_interrupt_active = 0x4000, // SDIO_INT_ACTIVE 8.131 - Status_programming_done = 0x2000, // PRG_DONE 8.132 - Status_data_transfer_done = 0x1000, // DATA_TRAN_DONE 8.133 - Status_end_command_response = 0x0800, // END_CMD_RES 8.134 - Status_data_fifo_almost_full = 0x0400, // DATA_FIFO_AFULL 8.135 - Status_read_wait = 0x0200, // IS_READWAIT 8.136 - Status_clock_enabled = 0x0100, // CLK_EN 8.137 - Status_data_fifo_full = 0x0080, // DATA_FIFO_FULL 8.138 - Status_data_fifo_empty = 0x0040, // DATA_FIFO_EMPTY 8.139 - Status_response_crc_error = 0x0020, // CRC_RES_ERR 8.140 - Status_read_crc_error = 0x0010, // CRC_READ_ERROR 8.141 - Status_write_crc_error_no_status = 0x0008, // CRC_WRITE_ERROR (2) 8.142 - Status_write_crc_error_data = 0x0004, // CRC_WRITE_ERROR (1) 8.143 - Status_timeout_response = 0x0002, // TIME_OUT_RES 8.144 - Status_timeout_read = 0x0001, // TIME_OUT_READ 8.145 -}; 8.146 - 8.147 -enum Clock_rate_bits : unsigned 8.148 -{ 8.149 - Clock_rate_field_mask = 0x7, // CLK_RATE 8.150 - Clock_rate_field_shift = 0, 8.151 -}; 8.152 - 8.153 -enum Command_data_control_bits : unsigned 8.154 -{ 8.155 - // JZ4780/X1600 only. 8.156 - 8.157 - Cdc_ccs_expected = 0x80000000, // CCS_EXPECTED 8.158 - Cdc_read_ce_ata = 0x40000000, // READ_CEATA 8.159 - Cdc_disable_boot = 0x08000000, // DIS_BOOT 8.160 - Cdc_expect_boot_ack = 0x02000000, // EXP_BOOT_ACK 8.161 - Cdc_alternative_boot_mode = 0x01000000, // BOOT_MODE 8.162 - 8.163 - // JZ4780 only. 8.164 - 8.165 - Cdc_auto_cmd23 = 0x00040000, // AUTO_CMD23 8.166 - 8.167 - // JZ4780/X1600 only. 8.168 - 8.169 - Cdc_sdio_interrupt_2cycle = 0x00020000, // SDIO_PRDT 8.170 - Cdc_auto_cmd12 = 0x00010000, // AUTO_CMD12 8.171 - 8.172 - Cdc_recv_fifo_level_field_mask = 0x3, // RTRG 8.173 - Cdc_fifo_level_16 = 0, 8.174 - Cdc_fifo_level_32 = 1, 8.175 - Cdc_fifo_level_64 = 2, 8.176 - Cdc_fifo_level_96 = 3, 8.177 - Cdc_recv_fifo_level_field_shift = 14, 8.178 - 8.179 - Cdc_trans_fifo_level_field_mask = 0x3, // TTRG 8.180 - Cdc_trans_fifo_level_field_shift = 12, 8.181 - 8.182 - // Common. 8.183 - 8.184 - Cdc_io_abort = 0x0800, // IO_ABORT 8.185 - 8.186 - Cdc_bus_width_field_mask = 0x3, // BUS_WIDTH 8.187 - Cdc_bus_width_field_1bit = 0, // = 0 8.188 - Cdc_bus_width_field_4bit = 2, // = 2 8.189 - Cdc_bus_width_field_shift = 9, 8.190 - 8.191 - // JZ4740 only. 8.192 - 8.193 - Cdc_dma_enable = 0x0100, // DMA_EN 8.194 - Cdc_dma_disable = 0x0000, 8.195 - 8.196 - // Common. 8.197 - 8.198 - Cdc_init_sequence = 0x0080, // INIT 8.199 - 8.200 - Cdc_expect_busy = 0x0040, // BUSY 8.201 - Cdc_do_not_expect_busy = 0x0000, 8.202 - 8.203 - Cdc_stream_block = 0x0020, // STREAM_BLOCK 8.204 - Cdc_not_stream_block = 0x0000, 8.205 - 8.206 - Cdc_write_operation = 0x0010, // WRITE_READ 8.207 - Cdc_read_operation = 0x0000, 8.208 - 8.209 - Cdc_data_with_command = 0x0008, // DATA_EN 8.210 - Cdc_no_data_with_command = 0x0000, 8.211 - 8.212 - Cdc_response_format_field_mask = 0x7, // RESPONSE_FORMAT 8.213 - Cdc_response_format_field_shift = 0, 8.214 -}; 8.215 - 8.216 -enum Response_timeout_bits : unsigned 8.217 -{ 8.218 - // NOTE: 16-bit value in the JZ4780. 8.219 - // NOTE: 32-bit value in the X1600. 8.220 - 8.221 - Response_timeout_mask = 0x000000ff, // RES_TO 8.222 -}; 8.223 - 8.224 -enum Read_timeout_bits : unsigned 8.225 -{ 8.226 - // NOTE: 16-bit value prior to the JZ4780/X1600. 8.227 - 8.228 - Read_timeout_mask = 0xffffffff, // READ_TO 8.229 -}; 8.230 - 8.231 -enum Block_length_bits : unsigned 8.232 -{ 8.233 - // NOTE: 16-bit value in the JZ4780/X1600. 8.234 - 8.235 - Block_length_mask = 0x00000fff, // BLK_LEN 8.236 -}; 8.237 - 8.238 -enum Block_count_bits : unsigned 8.239 -{ 8.240 - Block_count_mask = 0x0000ffff, // NOB/SNOB 8.241 -}; 8.242 - 8.243 -// Interrupt mask/flag bits. 8.244 - 8.245 -enum Interrupt_bits : unsigned 8.246 -{ 8.247 - // X1600 only. 8.248 - 8.249 - Int_dma_data_done = 0x80000000, // DMA_DATA_DONE 8.250 - 8.251 - // JZ4780 only. 8.252 - 8.253 - Int_auto_cmd23_done = 0x40000000, // AUTO_CMD23_DONE 8.254 - Int_signal_voltage_change = 0x20000000, // SVS 8.255 - 8.256 - // JZ4780/X1600 only. 8.257 - 8.258 - Int_pin_level_field_mask = 0x1f, // PIN_LEVEL 8.259 - Int_pin_level_field_shift = 24, 8.260 - 8.261 - // X1600 only. 8.262 - 8.263 - Int_write_request_all_done = 0x00800000, // WR_ALL_DONE 8.264 - 8.265 - // JZ4780/X1600 only. 8.266 - 8.267 - Int_boot_crc_error = 0x00100000, // BCE 8.268 - Int_boot_data_end = 0x00080000, // BDE 8.269 - Int_boot_ack_error = 0x00040000, // BAE 8.270 - Int_boot_ack_received = 0x00020000, // BAR 8.271 - Int_dma_end = 0x00010000, // DMAEND 8.272 - Int_auto_cmd12_done = 0x00008000, // AUTO_CMD12_DONE 8.273 - Int_data_fifo_full = 0x00004000, // DATA_FIFO_FULL 8.274 - Int_data_fifo_empty = 0x00002000, // DATA_FIFO_EMP 8.275 - Int_crc_response_error = 0x00001000, // CRC_RES_ERR 8.276 - Int_crc_read_error = 0x00000800, // CRC_READ_ERR 8.277 - Int_crc_write_error = 0x00000400, // CRC_WRITE_ERR 8.278 - Int_response_timeout = 0x00000200, // TIME_OUT_RES 8.279 - Int_read_timeout = 0x00000100, // TIME_OUT_READ 8.280 - 8.281 - // Common. 8.282 - 8.283 - Int_sdio = 0x80, // SDIO 8.284 - Int_trans_fifo_write_request = 0x40, // TXFIFO_WR_REQ 8.285 - Int_recv_fifo_read_request = 0x20, // RXFIFO_RD_REQ 8.286 - Int_end_command_response = 0x04, // END_CMD_RES 8.287 - Int_programming_done = 0x02, // PRG_DONE 8.288 - Int_data_transfer_done = 0x01, // DATA_TRAN_DONE 8.289 -}; 8.290 - 8.291 -enum Command_index_bits : unsigned 8.292 -{ 8.293 - Command_index_mask = 0x0000003f, // CMD_INDEX 8.294 -}; 8.295 - 8.296 -enum Command_argument_bits : unsigned 8.297 -{ 8.298 - Command_argument_mask = 0xffffffff, // ARG 8.299 -}; 8.300 - 8.301 -enum Response_fifo_bits : unsigned 8.302 -{ 8.303 - Response_fifo_mask = 0x0000ffff, // DATA 8.304 -}; 8.305 - 8.306 -enum Recv_data_fifo_bits : unsigned 8.307 -{ 8.308 - Recv_data_fifo_mask = 0xffffffff, // DATA 8.309 -}; 8.310 - 8.311 -enum Trans_data_fifo_bits : unsigned 8.312 -{ 8.313 - Trans_data_fifo_mask = 0xffffffff, // DATA 8.314 -}; 8.315 - 8.316 -enum Low_power_mode_bits : unsigned 8.317 -{ 8.318 - Low_power_mode_enable = 0x00000001, // LPM 8.319 -}; 8.320 - 8.321 -enum Dma_control_bits : unsigned 8.322 -{ 8.323 - Dma_mode_specify_transfer_length = 0x80, // MODE_SEL 8.324 - 8.325 - Dma_address_offset_field_mask = 0x3, // AOFST 8.326 - Dma_address_offset_field_shift = 5, 8.327 - 8.328 - Dma_align_enable = 0x10, // ALIGNEN 8.329 - 8.330 - Dma_burst_type_field_mask = 0x3, // INCR 8.331 - Dma_burst_type_incr16 = 0, 8.332 - Dma_burst_type_incr32 = 1, 8.333 - Dma_burst_type_incr64 = 2, 8.334 - Dma_burst_type_field_shift = 2, 8.335 - 8.336 - Dma_select_common_dma = 0x02, // DMASEL 8.337 - Dma_select_special_dma = 0x00, 8.338 - 8.339 - Dma_enable = 0x01, // DMAEN 8.340 - Dma_disable = 0x00, 8.341 -}; 8.342 - 8.343 - 8.344 - 8.345 -// Command indexes. 8.346 - 8.347 -enum Command_index : unsigned 8.348 -{ 8.349 - Command_go_idle_state = 0, 8.350 - Command_send_op_cond = 1, 8.351 - Command_all_send_cid = 2, 8.352 - Command_send_relative_addr = 3, // SD 8.353 - Command_set_relative_addr = 3, // MMC 8.354 - Command_set_dsr = 4, 8.355 - Command_io_send_op_cond = 5, // SDIO 8.356 - Command_select_deselect_card = 7, 8.357 - Command_send_if_cond = 8, 8.358 - Command_send_csd = 9, 8.359 - Command_send_cid = 10, 8.360 - Command_read_dat_until_stop = 11, 8.361 - Command_stop_transmission = 12, 8.362 - Command_send_status = 13, 8.363 - Command_go_inactive_state = 15, 8.364 - Command_set_blocklen = 16, 8.365 - Command_read_single_block = 17, 8.366 - Command_read_multiple_block = 18, 8.367 - Command_write_dat_until_stop = 20, 8.368 - Command_set_block_count = 23, 8.369 - Command_write_block = 24, 8.370 - Command_write_multiple_block = 25, 8.371 - Command_program_cid = 26, 8.372 - Command_program_csd = 27, 8.373 - Command_set_write_prot = 28, 8.374 - Command_clr_write_prot = 29, 8.375 - Command_send_write_prot = 30, 8.376 - Command_tag_sector_start = 32, 8.377 - Command_tag_sector_end = 33, 8.378 - Command_untag_sector = 34, 8.379 - Command_tag_erase_group_start = 35, 8.380 - Command_tag_erase_group_end = 36, 8.381 - Command_untag_erase_group = 37, 8.382 - Command_erase = 38, 8.383 - Command_fast_io = 39, 8.384 - Command_go_irq_state = 40, 8.385 - Command_lock_unlock = 42, 8.386 - Command_io_rw_direct = 52, // SDIO 8.387 - Command_app_cmd = 55, 8.388 - Command_gen_cmd = 56, 8.389 -}; 8.390 - 8.391 -// Application-specific command indexes, used by first issuing Command_app_cmd. 8.392 - 8.393 -enum App_command_index : unsigned 8.394 -{ 8.395 - App_command_set_bus_width = 6, 8.396 - App_command_sd_status = 13, 8.397 - App_command_send_num_wr_blocks = 22, 8.398 - App_command_set_wr_block_erase_count = 23, 8.399 - App_command_sd_send_op_cond = 41, 8.400 - App_command_set_clr_card_detect = 42, 8.401 - App_command_send_scr = 51, 8.402 - App_command_read_ocr = 58, 8.403 -}; 8.404 - 8.405 -enum Bus_width_bits : unsigned 8.406 -{ 8.407 - Bus_width_1bit = 0, 8.408 - Bus_width_4bit = 2, 8.409 -}; 8.410 - 8.411 -// Command response sizes in 16-bit units. 8.412 - 8.413 -enum Response_sizes : unsigned 8.414 -{ 8.415 - Response_size_R1 = 3, 8.416 - Response_size_R2 = 8, // omits the CRC and end bit 8.417 - Response_size_R3 = 3, 8.418 - Response_size_R4 = 3, 8.419 - Response_size_R5 = 3, 8.420 - Response_size_R6 = 3, 8.421 - Response_size_R7 = 3, 8.422 -}; 8.423 - 8.424 -// SD_SEND_OP_COND argument flags. 8.425 - 8.426 -enum Ocr_argument_flags : unsigned 8.427 -{ 8.428 - Ocr_high_capacity_storage = 0x40000000, 8.429 -}; 8.430 - 8.431 -// SD_SEND_OP_COND response flags (R3). 8.432 - 8.433 -enum Ocr_response_flags : unsigned 8.434 -{ 8.435 - Ocr_card_powered_up = 0x80000000, 8.436 -}; 8.437 - 8.438 -// R1 status flags. 8.439 - 8.440 -enum R1_status_flags : unsigned 8.441 -{ 8.442 - R1_status_error_mask = 0xffff0000, 8.443 -}; 8.444 - 8.445 - 8.446 - 8.447 -// MMC response structures. 8.448 -// These are 16-bit aligned to permit conversion to 16-bit arrays. 8.449 - 8.450 -struct R1 8.451 -{ 8.452 - uint8_t end_crc; 8.453 - uint32_t status; 8.454 - uint8_t index:6, trans_start:2; 8.455 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.456 - 8.457 -struct R2 8.458 -{ 8.459 - // uint8_t end_crc; (not retrieved) 8.460 - 8.461 - union 8.462 - { 8.463 - uint8_t raw[15]; 8.464 - struct CID cid; 8.465 - struct CSD csd; 8.466 - } payload; 8.467 - 8.468 - uint8_t reserved_trans_start; 8.469 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.470 - 8.471 -struct R3 8.472 -{ 8.473 - uint8_t end_reserved; 8.474 - uint32_t ocr; 8.475 - uint8_t reserved_trans_start; 8.476 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.477 - 8.478 -// SDIO response structures. 8.479 - 8.480 -struct R4 8.481 -{ 8.482 - uint8_t end_reserved; 8.483 - uint32_t ocr:24, stuff:3, memory_present:1, number_io_functions:3, ready:1; 8.484 - uint8_t reserved_trans_start; 8.485 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.486 - 8.487 -struct R5 8.488 -{ 8.489 - uint8_t end_crc; 8.490 - uint8_t data; 8.491 - uint8_t out_of_range:1, invalid_function_number:1, reserved:1, error:1, 8.492 - io_current_state:2, illegal_command:1, crc_error:1; 8.493 - uint16_t stuff; 8.494 - uint8_t index:6, trans_start:2; 8.495 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.496 - 8.497 -struct R6 8.498 -{ 8.499 - uint8_t end_crc; 8.500 - uint16_t status; 8.501 - uint16_t rca; 8.502 - uint8_t index:6, trans_start:2; 8.503 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.504 - 8.505 -struct R7 8.506 -{ 8.507 - uint8_t end_crc; 8.508 - 8.509 - union 8.510 - { 8.511 - uint32_t check:8, voltage:4, reserved:20; 8.512 - uint32_t raw; 8.513 - } check_voltage; 8.514 - 8.515 - uint8_t index:6, trans_start:2; 8.516 -} __attribute__((packed,aligned(__alignof__(uint16_t)))); 8.517 +#include "msc-defs.h" 8.518 8.519 8.520 8.521 @@ -580,8 +76,9 @@ 8.522 8.523 // Channel abstraction. 8.524 8.525 -Msc_channel::Msc_channel(l4_addr_t msc_start, l4_addr_t addr, l4_cap_idx_t irq) 8.526 -: _msc_start(msc_start), _irq(irq) 8.527 +Msc_channel::Msc_channel(l4_addr_t msc_start, l4_addr_t addr, l4_cap_idx_t irq, 8.528 + Cpm_chip *cpm, enum Clock_identifiers clock) 8.529 +: _msc_start(msc_start), _irq(irq), _cpm(cpm), _clock(clock) 8.530 { 8.531 _regs = new Hw::Mmio_register_block<32>(addr); 8.532 } 8.533 @@ -606,6 +103,64 @@ 8.534 } 8.535 8.536 bool 8.537 +Msc_channel::set_clock_frequency(uint64_t frequency) 8.538 +{ 8.539 + uint64_t division = _cpm->get_frequency(_clock) / frequency; 8.540 + double divider = ceil(log2(division)); 8.541 + 8.542 + if ((divider < 0) || (divider > Clock_rate_field_mask)) 8.543 + return false; 8.544 + 8.545 + set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 8.546 + (uint32_t) divider); 8.547 + 8.548 + return true; 8.549 +} 8.550 + 8.551 +void 8.552 +Msc_channel::reset() 8.553 +{ 8.554 + _regs[Msc_control] = _regs[Msc_control] | Control_reset; 8.555 + 8.556 + while (_regs[Msc_status] & Status_resetting); 8.557 +} 8.558 + 8.559 +void 8.560 +Msc_channel::start_clock() 8.561 +{ 8.562 + set_field(Msc_control, Control_clock_control_field_mask, 8.563 + Control_clock_control_field_shift, Control_clock_control_start); 8.564 + 8.565 + while (!(_regs[Msc_status] & Status_clock_enabled)); 8.566 +} 8.567 + 8.568 +void 8.569 +Msc_channel::stop_clock() 8.570 +{ 8.571 + set_field(Msc_control, Control_clock_control_field_mask, 8.572 + Control_clock_control_field_shift, Control_clock_control_stop); 8.573 + 8.574 + while (_regs[Msc_status] & Status_clock_enabled); 8.575 +} 8.576 + 8.577 +void 8.578 +Msc_channel::ack_irq(uint32_t flags) 8.579 +{ 8.580 + // Clear the flags by setting them. 8.581 + 8.582 + _regs[Msc_interrupt_flag] = _regs[Msc_interrupt_flag] | flags; 8.583 +} 8.584 + 8.585 +void 8.586 +Msc_channel::unmask_irq(uint32_t flags) 8.587 +{ 8.588 + ack_irq(flags); 8.589 + 8.590 + if (_regs[Msc_interrupt_mask] & flags) 8.591 + _regs[Msc_interrupt_mask] = _regs[Msc_interrupt_mask] & ~flags; 8.592 +} 8.593 + 8.594 +bool 8.595 Msc_channel::command_will_write(uint8_t index) 8.596 { 8.597 // NOTE: Probably incomplete coverage. 8.598 @@ -765,55 +320,6 @@ 8.599 } 8.600 } 8.601 8.602 -void 8.603 -Msc_channel::ack_irq(uint32_t flags) 8.604 -{ 8.605 - // Clear the flags by setting them. 8.606 - 8.607 - _regs[Msc_interrupt_flag] = _regs[Msc_interrupt_flag] | flags; 8.608 -} 8.609 - 8.610 -void 8.611 -Msc_channel::unmask_irq(uint32_t flags) 8.612 -{ 8.613 - ack_irq(flags); 8.614 - 8.615 - if (_regs[Msc_interrupt_mask] & flags) 8.616 - _regs[Msc_interrupt_mask] = _regs[Msc_interrupt_mask] & ~flags; 8.617 -} 8.618 - 8.619 -void 8.620 -Msc_channel::reset() 8.621 -{ 8.622 - _regs[Msc_control] = _regs[Msc_control] | Control_reset; 8.623 - 8.624 - // NOTE: X1600 and other recent SoCs only. 8.625 - 8.626 - _regs[Msc_control] = _regs[Msc_control] & ~Control_reset; 8.627 - 8.628 - // Sufficient for other SoCs... 8.629 - 8.630 - while (_regs[Msc_status] & Status_resetting); 8.631 -} 8.632 - 8.633 -void 8.634 -Msc_channel::start_clock() 8.635 -{ 8.636 - set_field(Msc_control, Control_clock_control_field_mask, 8.637 - Control_clock_control_field_shift, Control_clock_control_start); 8.638 - 8.639 - while (!(_regs[Msc_status] & Status_clock_enabled)); 8.640 -} 8.641 - 8.642 -void 8.643 -Msc_channel::stop_clock() 8.644 -{ 8.645 - set_field(Msc_control, Control_clock_control_field_mask, 8.646 - Control_clock_control_field_shift, Control_clock_control_stop); 8.647 - 8.648 - while (_regs[Msc_status] & Status_clock_enabled); 8.649 -} 8.650 - 8.651 // Send an application-specific command. 8.652 8.653 bool 8.654 @@ -1188,9 +694,10 @@ 8.655 reset(); 8.656 8.657 // Slow the clock for initialisation. 8.658 - // NOTE: Should use the CPM module to deduce the appropriate divider value. 8.659 + // NOTE: Should produce an error. 8.660 8.661 - set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 7); 8.662 + if (!set_clock_frequency(400000)) 8.663 + return; 8.664 8.665 send_command(Command_go_idle_state, 0); 8.666 8.667 @@ -1204,11 +711,6 @@ 8.668 identify_cards(); 8.669 query_cards(); 8.670 8.671 - // Restore the clock. 8.672 - // NOTE: Should use the CPM module to deduce the appropriate divider value. 8.673 - 8.674 - set_field(Msc_clock_rate, Clock_rate_field_mask, Clock_rate_field_shift, 1); 8.675 - 8.676 // Initially, no card is selected. 8.677 8.678 _card = -1; 8.679 @@ -1233,13 +735,16 @@ 8.680 // Receive data from the selected card. 8.681 8.682 uint32_t 8.683 -Msc_channel::recv_data(l4re_dma_space_dma_addr_t paddr, uint32_t count) 8.684 +Msc_channel::recv_data(struct dma_region *region, uint32_t count) 8.685 { 8.686 + if (count > region->size) 8.687 + return 0; 8.688 + 8.689 uint32_t flags = Int_data_transfer_done; 8.690 8.691 unmask_irq(flags); 8.692 8.693 - uint32_t to_transfer = transfer(_msc_start + Msc_recv_data_fifo, paddr, true, count); 8.694 + uint32_t to_transfer = transfer(_msc_start + Msc_recv_data_fifo, region->paddr, true, count); 8.695 8.696 wait_for_irq(flags); 8.697 ack_irq(flags); 8.698 @@ -1255,13 +760,16 @@ 8.699 // Send data to the selected card. 8.700 8.701 uint32_t 8.702 -Msc_channel::send_data(l4re_dma_space_dma_addr_t paddr, uint32_t count) 8.703 +Msc_channel::send_data(struct dma_region *region, uint32_t count) 8.704 { 8.705 + if (count > region->size) 8.706 + return 0; 8.707 + 8.708 uint32_t flags = Int_data_transfer_done; 8.709 8.710 unmask_irq(flags); 8.711 8.712 - uint32_t to_transfer = transfer(paddr, _msc_start + Msc_trans_data_fifo, false, count); 8.713 + uint32_t to_transfer = transfer(region->paddr, _msc_start + Msc_trans_data_fifo, false, count); 8.714 8.715 wait_for_irq(flags); 8.716 ack_irq(flags); 8.717 @@ -1277,7 +785,7 @@ 8.718 // Read blocks from the indicated card into a memory region. 8.719 8.720 uint32_t 8.721 -Msc_channel::read_blocks(uint8_t card, l4re_dma_space_dma_addr_t paddr, 8.722 +Msc_channel::read_blocks(uint8_t card, struct dma_region *region, 8.723 uint32_t block_address, uint32_t block_count) 8.724 { 8.725 uint32_t block_size = 1 << _cards[card].csd.read_blocklen; 8.726 @@ -1287,6 +795,13 @@ 8.727 8.728 if (_card != card) 8.729 { 8.730 + // Choose an appropriate clock frequency for the card. 8.731 + // NOTE: Should produce an error. 8.732 + 8.733 + if (!set_clock_frequency(_cards[card].csd.tran_speed == 0x32 ? 8.734 + 25000000 : 50000000)) 8.735 + return 0; 8.736 + 8.737 if (!send_command(Command_select_deselect_card, _cards[card].rca << 16)) 8.738 return 0; 8.739 8.740 @@ -1346,7 +861,7 @@ 8.741 8.742 // NOTE: Use Msc_block_success_count instead. 8.743 8.744 - uint32_t transferred = recv_data(paddr, block_size * block_count); 8.745 + uint32_t transferred = recv_data(region, block_size * block_count); 8.746 8.747 if (block_count > 1) 8.748 send_command(Command_stop_transmission, 0); 8.749 @@ -1358,7 +873,8 @@ 8.750 8.751 // Peripheral abstraction. 8.752 8.753 -Msc_chip::Msc_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 8.754 -: _msc_start(msc_start), _start(start), _end(end) 8.755 +Msc_chip::Msc_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 8.756 + Cpm_chip *cpm) 8.757 +: _msc_start(msc_start), _start(start), _end(end), _cpm(cpm) 8.758 { 8.759 }
9.1 --- a/pkg/devices/lib/msc/src/jz4780.cc Fri Feb 16 23:11:25 2024 +0100 9.2 +++ b/pkg/devices/lib/msc/src/jz4780.cc Sat Feb 17 23:04:12 2024 +0100 9.3 @@ -21,28 +21,20 @@ 9.4 9.5 #include <l4/sys/err.h> 9.6 9.7 +#include "msc-defs.h" 9.8 #include "msc-jz4780.h" 9.9 9.10 9.11 9.12 -// Register locations for each channel. 9.13 - 9.14 -enum Regs : unsigned 9.15 -{ 9.16 - // Channel block size/offset. 9.17 - 9.18 - Msc_channel_offset = 0x10000, 9.19 -}; 9.20 - 9.21 - 9.22 - 9.23 // Channel abstraction. 9.24 9.25 Msc_jz4780_channel::Msc_jz4780_channel(l4_addr_t msc_start, l4_addr_t addr, 9.26 - l4_cap_idx_t irq, Dma_jz4780_channel *dma, 9.27 + l4_cap_idx_t irq, 9.28 + Cpm_chip *cpm, enum Clock_identifiers clock, 9.29 + Dma_jz4780_channel *dma, 9.30 enum Dma_jz4780_request_type request_type_in, 9.31 enum Dma_jz4780_request_type request_type_out) 9.32 -: Msc_channel(msc_start, addr, irq), 9.33 +: Msc_channel(msc_start, addr, irq, cpm, clock), 9.34 _dma(dma), 9.35 _request_type_in(request_type_in), 9.36 _request_type_out(request_type_out) 9.37 @@ -77,25 +69,20 @@ 9.38 9.39 // Peripheral abstraction. 9.40 9.41 -Msc_jz4780_chip::Msc_jz4780_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 9.42 -: Msc_chip(msc_start, start, end) 9.43 +Msc_jz4780_chip::Msc_jz4780_chip(l4_addr_t msc_start, l4_addr_t start, 9.44 + l4_addr_t end, Cpm_chip *cpm) 9.45 +: Msc_chip(msc_start, start, end, cpm) 9.46 { 9.47 } 9.48 9.49 Msc_channel *Msc_jz4780_chip::get_channel(uint8_t channel, l4_cap_idx_t irq, 9.50 Dma_jz4780_channel *dma) 9.51 { 9.52 - const enum Dma_jz4780_request_type in_types[] = 9.53 - {Dma_request_msc0_in, Dma_request_msc1_in, Dma_request_msc2_in}; 9.54 - 9.55 - const enum Dma_jz4780_request_type out_types[] = 9.56 - {Dma_request_msc0_out, Dma_request_msc1_out, Dma_request_msc2_out}; 9.57 - 9.58 if (channel < num_channels()) 9.59 return new Msc_jz4780_channel(_msc_start + channel * Msc_channel_offset, 9.60 _start + channel * Msc_channel_offset, 9.61 - irq, dma, 9.62 - in_types[channel], out_types[channel]); 9.63 + irq, _cpm, _clocks[channel], dma, 9.64 + _in_types[channel], _out_types[channel]); 9.65 else 9.66 throw -L4_EINVAL; 9.67 } 9.68 @@ -104,9 +91,11 @@ 9.69 9.70 // C language interface functions. 9.71 9.72 -void *jz4780_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 9.73 +void *jz4780_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 9.74 + void *cpm) 9.75 { 9.76 - return (void *) new Msc_jz4780_chip(msc_start, start, end); 9.77 + return (void *) new Msc_jz4780_chip(msc_start, start, end, 9.78 + static_cast<Cpm_jz4780_chip *>(cpm)); 9.79 } 9.80 9.81 void *jz4780_msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, 9.82 @@ -132,9 +121,9 @@ 9.83 } 9.84 9.85 uint32_t jz4780_msc_read_blocks(void *msc_channel, uint8_t card, 9.86 - l4re_dma_space_dma_addr_t paddr, 9.87 + struct dma_region *region, 9.88 uint32_t block_address, uint32_t block_count) 9.89 { 9.90 - return static_cast<Msc_channel *>(msc_channel)->read_blocks(card, paddr, 9.91 + return static_cast<Msc_channel *>(msc_channel)->read_blocks(card, region, 9.92 block_address, block_count); 9.93 }
10.1 --- a/pkg/devices/lib/msc/src/x1600.cc Fri Feb 16 23:11:25 2024 +0100 10.2 +++ b/pkg/devices/lib/msc/src/x1600.cc Sat Feb 17 23:04:12 2024 +0100 10.3 @@ -21,34 +21,43 @@ 10.4 10.5 #include <l4/sys/err.h> 10.6 10.7 +#include "msc-defs.h" 10.8 #include "msc-x1600.h" 10.9 10.10 10.11 10.12 -// Register locations for each channel. 10.13 - 10.14 -enum Regs : unsigned 10.15 -{ 10.16 - // Channel block size/offset. 10.17 - 10.18 - Msc_channel_offset = 0x10000, 10.19 -}; 10.20 - 10.21 - 10.22 - 10.23 // Channel abstraction. 10.24 10.25 Msc_x1600_channel::Msc_x1600_channel(l4_addr_t msc_start, l4_addr_t addr, 10.26 - l4_cap_idx_t irq, Dma_x1600_channel *dma, 10.27 + l4_cap_idx_t irq, 10.28 + Cpm_chip *cpm, enum Clock_identifiers clock, 10.29 + Dma_x1600_channel *dma, 10.30 enum Dma_x1600_request_type request_type_in, 10.31 enum Dma_x1600_request_type request_type_out) 10.32 -: Msc_channel(msc_start, addr, irq), 10.33 +: Msc_channel(msc_start, addr, irq, cpm, clock), 10.34 _dma(dma), 10.35 _request_type_in(request_type_in), 10.36 _request_type_out(request_type_out) 10.37 { 10.38 } 10.39 10.40 +// Reset for X1600 and other recent SoCs only. 10.41 + 10.42 +void 10.43 +Msc_x1600_channel::reset() 10.44 +{ 10.45 + _regs[Msc_control] = _regs[Msc_control] | Control_reset; 10.46 + 10.47 + // NOTE: On the X1600, Msc_control tends to read as zero, anyway, making this 10.48 + // NOTE: equivalent to clearing the register. 10.49 + 10.50 + _regs[Msc_control] = _regs[Msc_control] & ~Control_reset; 10.51 + 10.52 + // Sufficient for other SoCs... 10.53 + 10.54 + while (_regs[Msc_status] & Status_resetting); 10.55 +} 10.56 + 10.57 // Request the transfer of the indicated number of bytes between two physical 10.58 // addresses in the indicated direction, returning the number of bytes to be 10.59 // transferred. 10.60 @@ -77,25 +86,20 @@ 10.61 10.62 // Peripheral abstraction. 10.63 10.64 -Msc_x1600_chip::Msc_x1600_chip(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 10.65 -: Msc_chip(msc_start, start, end) 10.66 +Msc_x1600_chip::Msc_x1600_chip(l4_addr_t msc_start, l4_addr_t start, 10.67 + l4_addr_t end, Cpm_chip *cpm) 10.68 +: Msc_chip(msc_start, start, end, cpm) 10.69 { 10.70 } 10.71 10.72 Msc_channel *Msc_x1600_chip::get_channel(uint8_t channel, l4_cap_idx_t irq, 10.73 Dma_x1600_channel *dma) 10.74 { 10.75 - const enum Dma_x1600_request_type in_types[] = 10.76 - {Dma_request_msc0_in, Dma_request_msc1_in}; 10.77 - 10.78 - const enum Dma_x1600_request_type out_types[] = 10.79 - {Dma_request_msc0_out, Dma_request_msc1_out}; 10.80 - 10.81 if (channel < num_channels()) 10.82 return new Msc_x1600_channel(_msc_start + channel * Msc_channel_offset, 10.83 _start + channel * Msc_channel_offset, 10.84 - irq, dma, 10.85 - in_types[channel], out_types[channel]); 10.86 + irq, _cpm, _clocks[channel], dma, 10.87 + _in_types[channel], _out_types[channel]); 10.88 else 10.89 throw -L4_EINVAL; 10.90 } 10.91 @@ -104,9 +108,11 @@ 10.92 10.93 // C language interface functions. 10.94 10.95 -void *x1600_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 10.96 +void *x1600_msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, 10.97 + void *cpm) 10.98 { 10.99 - return (void *) new Msc_x1600_chip(msc_start, start, end); 10.100 + return (void *) new Msc_x1600_chip(msc_start, start, end, 10.101 + static_cast<Cpm_x1600_chip *>(cpm)); 10.102 } 10.103 10.104 void *x1600_msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, 10.105 @@ -132,9 +138,9 @@ 10.106 } 10.107 10.108 uint32_t x1600_msc_read_blocks(void *msc_channel, uint8_t card, 10.109 - l4re_dma_space_dma_addr_t paddr, 10.110 + struct dma_region *region, 10.111 uint32_t block_address, uint32_t block_count) 10.112 { 10.113 - return static_cast<Msc_channel *>(msc_channel)->read_blocks(card, paddr, 10.114 + return static_cast<Msc_channel *>(msc_channel)->read_blocks(card, region, 10.115 block_address, block_count); 10.116 }
11.1 --- a/pkg/devices/util/include/dma.h Fri Feb 16 23:11:25 2024 +0100 11.2 +++ b/pkg/devices/util/include/dma.h Sat Feb 17 23:04:12 2024 +0100 11.3 @@ -1,7 +1,7 @@ 11.4 /* 11.5 * DMA-related memory allocation utility functions. 11.6 * 11.7 - * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 11.8 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk> 11.9 * 11.10 * This program is free software; you can redistribute it and/or 11.11 * modify it under the terms of the GNU General Public License as 11.12 @@ -24,9 +24,17 @@ 11.13 #include <l4/re/c/dma_space.h> 11.14 #include <l4/sys/types.h> 11.15 11.16 +struct dma_region 11.17 +{ 11.18 + unsigned int size; 11.19 + unsigned int align; 11.20 + l4_addr_t vaddr; 11.21 + l4re_dma_space_dma_addr_t paddr; 11.22 + l4_cap_idx_t mem; 11.23 +}; 11.24 + 11.25 EXTERN_C_BEGIN 11.26 11.27 -long get_dma_region(unsigned long size, int align, l4_addr_t *vaddr, 11.28 - l4re_dma_space_dma_addr_t *paddr, l4_cap_idx_t *mem); 11.29 +long get_dma_region(unsigned long size, int align, struct dma_region *region); 11.30 11.31 EXTERN_C_END
12.1 --- a/pkg/devices/util/src/dma.cc Fri Feb 16 23:11:25 2024 +0100 12.2 +++ b/pkg/devices/util/src/dma.cc Sat Feb 17 23:04:12 2024 +0100 12.3 @@ -1,7 +1,7 @@ 12.4 /* 12.5 * DMA-related memory allocation utility functions. 12.6 * 12.7 - * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 12.8 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk> 12.9 * 12.10 * This program is free software; you can redistribute it and/or 12.11 * modify it under the terms of the GNU General Public License as 12.12 @@ -38,13 +38,15 @@ 12.13 12.14 // Allocate a memory region of the given size for DMA. 12.15 12.16 -long get_dma_region(unsigned long size, int align, l4_addr_t *vaddr, 12.17 - l4re_dma_space_dma_addr_t *paddr, l4_cap_idx_t *mem) 12.18 +long get_dma_region(unsigned long size, int align, struct dma_region *region) 12.19 { 12.20 // Memory allocation capabilities. 12.21 12.22 l4_cap_idx_t dma, vbus; 12.23 12.24 + region->size = 0; 12.25 + region->align = 0; 12.26 + 12.27 // Obtain capabilities for the DMA region and the vbus. 12.28 12.29 dma = ipc_cap_alloc(); 12.30 @@ -82,21 +84,21 @@ 12.31 12.32 // Map the allocated memory, obtaining a virtual address. 12.33 12.34 - *vaddr = 0; 12.35 + region->vaddr = 0; 12.36 12.37 - if (ipc_new_dataspace(size, alloc_flags, align, mem)) 12.38 + if (ipc_new_dataspace(size, alloc_flags, align, ®ion->mem)) 12.39 return -L4_ENOMEM; 12.40 12.41 - if (ipc_attach_dataspace_align(*mem, size, attach_flags, align, (void **) vaddr)) 12.42 + if (ipc_attach_dataspace_align(region->mem, size, attach_flags, align, (void **) ®ion->vaddr)) 12.43 return -L4_ENOMEM; 12.44 12.45 // Obtain a physical address. 12.46 12.47 l4_size_t size_out = size; 12.48 - *paddr = 0; 12.49 + region->paddr = 0; 12.50 12.51 - if (l4re_dma_space_map(dma, *mem | L4_CAP_FPAGE_RW, 0, &size_out, 0, 12.52 - L4RE_DMA_SPACE_TO_DEVICE, paddr)) 12.53 + if (l4re_dma_space_map(dma, region->mem | L4_CAP_FPAGE_RW, 0, &size_out, 0, 12.54 + L4RE_DMA_SPACE_TO_DEVICE, ®ion->paddr)) 12.55 return -L4_ENOMEM; 12.56 12.57 // Test the mapped region size. 12.58 @@ -104,5 +106,8 @@ 12.59 if (size_out != size) 12.60 return -L4_ENOMEM; 12.61 12.62 + region->size = size_out; 12.63 + region->align = align; 12.64 + 12.65 return L4_EOK; 12.66 }
13.1 --- a/pkg/landfall-examples/hw_info/common.h Fri Feb 16 23:11:25 2024 +0100 13.2 +++ b/pkg/landfall-examples/hw_info/common.h Sat Feb 17 23:04:12 2024 +0100 13.3 @@ -22,10 +22,10 @@ 13.4 13.5 #pragma once 13.6 13.7 -#include <l4/re/c/dma_space.h> 13.8 +#include <l4/devices/clocks.h> 13.9 +#include <l4/devices/dma.h> 13.10 +#include <l4/devices/gpio.h> 13.11 #include <l4/sys/types.h> 13.12 -#include <l4/devices/clocks.h> 13.13 -#include <l4/devices/gpio.h> 13.14 #include <stdint.h> 13.15 13.16 13.17 @@ -168,7 +168,7 @@ 13.18 13.19 /* MSC adapter functions. */ 13.20 13.21 -void *msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end); 13.22 +void *msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, void *cpm); 13.23 13.24 void *msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, void *dma); 13.25 13.26 @@ -179,7 +179,7 @@ 13.27 void msc_enable(void *msc_channel); 13.28 13.29 uint32_t msc_read_blocks(void *msc_channel, uint8_t card, 13.30 - l4re_dma_space_dma_addr_t paddr, 13.31 + struct dma_region *region, 13.32 uint32_t block_address, uint32_t block_count); 13.33 13.34 13.35 @@ -311,19 +311,6 @@ 13.36 13.37 13.38 13.39 -/* DMA definitions. */ 13.40 - 13.41 -struct dma_region 13.42 -{ 13.43 - unsigned int size; 13.44 - unsigned int align; 13.45 - l4_addr_t vaddr; 13.46 - l4re_dma_space_dma_addr_t paddr; 13.47 - l4_cap_idx_t mem; 13.48 -}; 13.49 - 13.50 - 13.51 - 13.52 /* GPIO definitions. */ 13.53 13.54 struct gpio_port
14.1 --- a/pkg/landfall-examples/hw_info/hw_info.c Fri Feb 16 23:11:25 2024 +0100 14.2 +++ b/pkg/landfall-examples/hw_info/hw_info.c Sat Feb 17 23:04:12 2024 +0100 14.3 @@ -582,7 +582,7 @@ 14.4 if (!read_number("Alignment", ®ion->align)) 14.5 return; 14.6 14.7 - if (get_dma_region(region->size, region->align, ®ion->vaddr, ®ion->paddr, ®ion->mem)) 14.8 + if (get_dma_region(region->size, region->align, region)) 14.9 printf("Could not allocate region.\n"); 14.10 } 14.11 14.12 @@ -1185,7 +1185,7 @@ 14.13 14.14 l4_cache_inv_data(dma_region->vaddr, dma_region->vaddr + dma_region->size); 14.15 14.16 - transferred = msc_read_blocks(channel, (uint8_t) card, dma_region->paddr, 0, 1); 14.17 + transferred = msc_read_blocks(channel, (uint8_t) card, dma_region, 0, 1); 14.18 14.19 if (!transferred) 14.20 { 14.21 @@ -1306,7 +1306,7 @@ 14.22 14.23 l4_cache_inv_data(dma_region->vaddr, dma_region->vaddr + dma_region->size); 14.24 14.25 - transferred = msc_read_blocks(channel, (uint8_t) card, dma_region->paddr, 14.26 + transferred = msc_read_blocks(channel, (uint8_t) card, dma_region, 14.27 block_address, block_count); 14.28 14.29 printf("Transferred: %d\n", transferred); 14.30 @@ -2051,7 +2051,7 @@ 14.31 14.32 printf("MSC at 0x%lx...0x%lx.\n", msc_base, msc_base_end); 14.33 14.34 - msc = msc_init(msc_phys_base, msc_base, msc_base_end); 14.35 + msc = msc_init(msc_phys_base, msc_base, msc_base_end, cpm); 14.36 14.37 if (get_irq(io_memory_regions[MSC], &msc_irq_start, &msc_irq_end) < 0) 14.38 return 1;
15.1 --- a/pkg/landfall-examples/hw_info/jz4780.c Fri Feb 16 23:11:25 2024 +0100 15.2 +++ b/pkg/landfall-examples/hw_info/jz4780.c Sat Feb 17 23:04:12 2024 +0100 15.3 @@ -339,9 +339,9 @@ 15.4 15.5 /* MSC adapter functions. */ 15.6 15.7 -void *msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 15.8 +void *msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, void *cpm) 15.9 { 15.10 - return jz4780_msc_init(msc_start, start, end); 15.11 + return jz4780_msc_init(msc_start, start, end, cpm); 15.12 } 15.13 15.14 void *msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, void *dma) 15.15 @@ -365,10 +365,10 @@ 15.16 } 15.17 15.18 uint32_t msc_read_blocks(void *msc_channel, uint8_t card, 15.19 - l4re_dma_space_dma_addr_t paddr, 15.20 + struct dma_region *region, 15.21 uint32_t block_address, uint32_t block_count) 15.22 { 15.23 - return jz4780_msc_read_blocks(msc_channel, card, paddr, block_address, 15.24 + return jz4780_msc_read_blocks(msc_channel, card, region, block_address, 15.25 block_count); 15.26 } 15.27
16.1 --- a/pkg/landfall-examples/hw_info/x1600.c Fri Feb 16 23:11:25 2024 +0100 16.2 +++ b/pkg/landfall-examples/hw_info/x1600.c Sat Feb 17 23:04:12 2024 +0100 16.3 @@ -328,9 +328,9 @@ 16.4 16.5 /* MSC adapter functions. */ 16.6 16.7 -void *msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end) 16.8 +void *msc_init(l4_addr_t msc_start, l4_addr_t start, l4_addr_t end, void *cpm) 16.9 { 16.10 - return x1600_msc_init(msc_start, start, end); 16.11 + return x1600_msc_init(msc_start, start, end, cpm); 16.12 } 16.13 16.14 void *msc_get_channel(void *msc, uint8_t channel, l4_cap_idx_t irq, void *dma) 16.15 @@ -354,10 +354,10 @@ 16.16 } 16.17 16.18 uint32_t msc_read_blocks(void *msc_channel, uint8_t card, 16.19 - l4re_dma_space_dma_addr_t paddr, 16.20 + struct dma_region *region, 16.21 uint32_t block_address, uint32_t block_count) 16.22 { 16.23 - return x1600_msc_read_blocks(msc_channel, card, paddr, block_address, 16.24 + return x1600_msc_read_blocks(msc_channel, card, region, block_address, 16.25 block_count); 16.26 } 16.27
17.1 --- a/pkg/landfall-examples/letux400_dma/letux400_dma.cc Fri Feb 16 23:11:25 2024 +0100 17.2 +++ b/pkg/landfall-examples/letux400_dma/letux400_dma.cc Sat Feb 17 23:04:12 2024 +0100 17.3 @@ -1,7 +1,7 @@ 17.4 /* 17.5 * Test DMA transfers. 17.6 * 17.7 - * Copyright (C) 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 17.8 + * Copyright (C) 2018, 2020, 2021, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 17.9 * 17.10 * This program is free software; you can redistribute it and/or 17.11 * modify it under the terms of the GNU General Public License as 17.12 @@ -60,12 +60,9 @@ 17.13 17.14 /* Allocate memory to test transfers. */ 17.15 17.16 - l4_cap_idx_t ds0_mem, ds1_mem; 17.17 - l4_size_t ds0_size = L4_PAGESIZE, ds1_size = L4_PAGESIZE; 17.18 - l4_addr_t ds0_addr, ds1_addr; 17.19 - l4re_dma_space_dma_addr_t ds0_paddr, ds1_paddr; 17.20 + struct dma_region ds0_region, ds1_region; 17.21 17.22 - err = get_dma_region(ds0_size, 8, &ds0_addr, &ds0_paddr, &ds0_mem); 17.23 + err = get_dma_region(L4_PAGESIZE, 8, &ds0_region); 17.24 17.25 if (err) 17.26 { 17.27 @@ -73,7 +70,7 @@ 17.28 return 1; 17.29 } 17.30 17.31 - err = get_dma_region(ds1_size, 8, &ds1_addr, &ds1_paddr, &ds1_mem); 17.32 + err = get_dma_region(L4_PAGESIZE, 8, &ds1_region); 17.33 17.34 if (err) 17.35 { 17.36 @@ -83,10 +80,10 @@ 17.37 17.38 /* Fill the allocated memory. */ 17.39 17.40 - memset((void *) ds0_addr, 0, ds0_size); 17.41 - memset((void *) ds1_addr, 0, ds1_size); 17.42 + memset((void *) ds0_region.vaddr, 0, ds0_region.size); 17.43 + memset((void *) ds1_region.vaddr, 0, ds1_region.size); 17.44 17.45 - sprintf((char *) ds0_addr, "The quick brown fox jumped over the lazy dog.\n"); 17.46 + sprintf((char *) ds0_region.vaddr, "The quick brown fox jumped over the lazy dog.\n"); 17.47 17.48 /* Interrupts. */ 17.49 17.50 @@ -186,12 +183,12 @@ 17.51 17.52 /* Transfer data between the allocated memory regions. */ 17.53 17.54 - printf("Transfer from %llx to %llx...\n", ds0_paddr, ds1_paddr); 17.55 + printf("Transfer from %llx to %llx...\n", ds0_region.paddr, ds1_region.paddr); 17.56 17.57 unsigned int count = L4_PAGESIZE / 4; 17.58 17.59 - unsigned int to_transfer = jz4730_dma_transfer(dma0, (uint32_t) ds0_paddr, 17.60 - (uint32_t) ds1_paddr, 17.61 + unsigned int to_transfer = jz4730_dma_transfer(dma0, (uint32_t) ds0_region.paddr, 17.62 + (uint32_t) ds1_region.paddr, 17.63 count, 17.64 1, 1, 17.65 4, 4, 17.66 @@ -201,8 +198,8 @@ 17.67 unsigned int transferred = to_transfer ? count - jz4730_dma_wait(dma0) : 0; 17.68 17.69 printf("Transferred: %d\n", transferred); 17.70 - printf("Source: %s\n", (char *) ds0_addr); 17.71 - printf("Destination: %s\n", (char *) ds1_addr); 17.72 + printf("Source: %s\n", (char *) ds0_region.vaddr); 17.73 + printf("Destination: %s\n", (char *) ds1_region.vaddr); 17.74 17.75 /* Detach from the interrupt. */ 17.76