1 /* 2 * DMA support for the X1600. 3 * 4 * Copyright (C) 2021, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <l4/devices/dma-x1600.h> 23 #include <l4/devices/hw_mmio_register_block.h> 24 25 #include <l4/sys/icu.h> 26 #include <l4/sys/ipc.h> 27 #include <l4/sys/irq.h> 28 #include <l4/util/util.h> 29 30 #include <stdio.h> 31 32 33 34 enum Global_regs 35 { 36 Dma_control = 0x1000, // DMAC 37 Dma_irq_pending = 0x1004, // DIRQP 38 }; 39 40 enum Channel_regs 41 { 42 Dma_source = 0x00, // DSA 43 Dma_destination = 0x04, // DTA 44 Dma_transfer_count = 0x08, // DTC 45 Dma_request_source = 0x0c, // DRT 46 Dma_control_status = 0x10, // DCS 47 Dma_command = 0x14, // DCM 48 Dma_descriptor_address = 0x18, // DDA 49 Dma_stride = 0x1c, // DSD 50 }; 51 52 enum Dma_control_bits : unsigned 53 { 54 Dma_fast_msc_transfer = 0x80000000, // FMSC 55 Dma_fast_ssi_transfer = 0x40000000, // FSSI 56 Dma_fast_tssi_transfer = 0x20000000, // FTSSI 57 Dma_fast_uart_transfer = 0x10000000, // FUART 58 Dma_fast_aic_transfer = 0x08000000, // FAIC 59 Dma_control_trans_halted = 0x00000008, // HLT 60 Dma_control_address_error = 0x00000004, // AR 61 Dma_control_enable = 0x00000001, // DMAE 62 }; 63 64 enum Dma_transfer_count_bits : unsigned 65 { 66 Dma_transfer_count_mask = 0x00ffffff, 67 }; 68 69 enum Dma_request_source_bits : unsigned 70 { 71 Dma_request_type_mask = 0x0000003f, 72 }; 73 74 enum Dma_control_status_bits : unsigned 75 { 76 Dma_no_descriptor_transfer = 0x80000000, 77 Dma_8word_descriptor = 0x40000000, 78 Dma_copy_offset_mask = 0x0000ff00, 79 Dma_address_error = 0x00000010, 80 Dma_trans_completed = 0x00000008, 81 Dma_trans_halted = 0x00000004, 82 Dma_channel_enable = 0x00000001, 83 84 Dma_copy_offset_shift = 8, 85 }; 86 87 enum Dma_command_bits : unsigned 88 { 89 Dma_source_address_increment = 0x800000, 90 Dma_source_address_no_increment = 0x000000, 91 Dma_destination_address_increment = 0x400000, 92 Dma_destination_address_no_increment = 0x000000, 93 94 Dma_source_address_increment_wrap = 0x200000, 95 Dma_destination_address_increment_wrap = 0x100000, 96 Dma_recommended_data_unit_size_mask = 0x0f0000, 97 Dma_source_port_width_mask = 0x00c000, 98 Dma_destination_port_width_mask = 0x003000, 99 Dma_transfer_unit_size_mask = 0x000f00, 100 101 Dma_trans_unit_size_32_bit = 0x000000, 102 Dma_trans_unit_size_8_bit = 0x000100, 103 Dma_trans_unit_size_16_bit = 0x000200, 104 Dma_trans_unit_size_16_byte = 0x000300, 105 Dma_trans_unit_size_32_byte = 0x000400, 106 Dma_trans_unit_size_64_byte = 0x000500, 107 Dma_trans_unit_size_128_byte = 0x000600, 108 Dma_trans_unit_size_autonomous = 0x000700, 109 Dma_trans_unit_size_external = 0x000800, 110 111 Dma_source_address_compare_index = 0x000080, 112 Dma_destination_address_compare_index = 0x000040, 113 Dma_stride_enable = 0x000004, 114 Dma_transfer_irq_enable = 0x000002, 115 Dma_descriptor_link_enable = 0x000001, 116 117 Dma_recommended_data_unit_size_shift = 16, 118 Dma_source_port_width_shift = 14, 119 Dma_destination_port_width_shift = 12, 120 Dma_transfer_unit_size_shift = 8, 121 }; 122 123 enum Dma_port_width_values : unsigned 124 { 125 Dma_port_width_32_bit = 0, 126 Dma_port_width_8_bit = 1, 127 Dma_port_width_16_bit = 2, 128 }; 129 130 131 132 // Initialise a channel. 133 134 Dma_x1600_channel::Dma_x1600_channel(Dma_x1600_chip *chip, uint8_t channel, 135 l4_addr_t start, l4_cap_idx_t irq) 136 : _chip(chip), _channel(channel), _irq(irq) 137 { 138 _regs = new Hw::Mmio_register_block<32>(start); 139 140 // Initialise the transfer count. 141 142 _regs[Dma_transfer_count] = 0; 143 } 144 145 // Return the closest interval length greater than or equal to the number of 146 // units given encoded in the request detection interval length field of the 147 // control/status register. 148 149 uint32_t 150 Dma_x1600_channel::encode_req_detect_int_length(uint8_t units) 151 { 152 static uint8_t lengths[] = {0, 1, 2, 3, 4, 8, 16, 32, 64, 128}; 153 int i; 154 155 if (!units) 156 return 0; 157 158 for (i = 0; i <= 9; i++) 159 { 160 if (lengths[i] >= units) 161 break; 162 } 163 164 return i << Dma_recommended_data_unit_size_shift; 165 } 166 167 // Encode the appropriate source port width for the given request type. 168 169 uint32_t 170 Dma_x1600_channel::encode_source_port_width(uint8_t width) 171 { 172 switch (width) 173 { 174 case 1: 175 return Dma_port_width_8_bit << Dma_source_port_width_shift; 176 177 case 2: 178 return Dma_port_width_16_bit << Dma_source_port_width_shift; 179 180 default: 181 return Dma_port_width_32_bit << Dma_source_port_width_shift; 182 } 183 } 184 185 // Encode the appropriate destination port width for the given request type. 186 187 uint32_t 188 Dma_x1600_channel::encode_destination_port_width(uint8_t width) 189 { 190 switch (width) 191 { 192 case 1: 193 return Dma_port_width_8_bit << Dma_destination_port_width_shift; 194 195 case 2: 196 return Dma_port_width_16_bit << Dma_destination_port_width_shift; 197 198 default: 199 return Dma_port_width_32_bit << Dma_destination_port_width_shift; 200 } 201 } 202 203 // Encode the transfer unit size. 204 // NOTE: This does not handle the external case. 205 206 uint32_t 207 Dma_x1600_channel::encode_transfer_unit_size(uint8_t size) 208 { 209 switch (size) 210 { 211 case 0: 212 return Dma_trans_unit_size_autonomous; 213 214 case 1: 215 return Dma_trans_unit_size_8_bit; 216 217 case 2: 218 return Dma_trans_unit_size_16_bit; 219 220 case 16: 221 return Dma_trans_unit_size_16_byte; 222 223 case 32: 224 return Dma_trans_unit_size_32_byte; 225 226 case 64: 227 return Dma_trans_unit_size_64_byte; 228 229 case 128: 230 return Dma_trans_unit_size_128_byte; 231 232 default: 233 return Dma_trans_unit_size_32_bit; 234 } 235 } 236 237 // Transfer data between memory locations. 238 239 unsigned int 240 Dma_x1600_channel::transfer(uint32_t source, uint32_t destination, 241 unsigned int count, 242 bool source_increment, bool destination_increment, 243 uint8_t source_width, uint8_t destination_width, 244 uint8_t transfer_unit_size, 245 enum Dma_x1600_request_type type) 246 { 247 printf("transfer:%s%s%s%s\n", error() ? " error" : "", 248 halted() ? " halted" : "", 249 completed() ? " completed" : "", 250 _regs[Dma_transfer_count] ? " count" : ""); 251 252 // Ensure an absence of address error and halt conditions globally and in this channel. 253 254 if (error() || halted()) 255 return 0; 256 257 // Ensure an absence of transaction completed and zero transfer count for this channel. 258 259 if (completed() || _regs[Dma_transfer_count]) 260 return 0; 261 262 // Disable the channel. 263 264 _regs[Dma_control_status] = _regs[Dma_control_status] & ~Dma_channel_enable; 265 266 // Set addresses. 267 268 _regs[Dma_source] = source; 269 _regs[Dma_destination] = destination; 270 271 // Set transfer count to the number of units. 272 273 unsigned int units = count < Dma_transfer_count_mask ? count : Dma_transfer_count_mask; 274 275 _regs[Dma_transfer_count] = units; 276 277 // Set auto-request for memory-to-memory transfers. Otherwise, set the 278 // indicated request type. 279 280 _regs[Dma_request_source] = type; 281 282 // For a descriptor, the actual fields would be populated instead of the 283 // command register, descriptor transfer would be indicated in the control/ 284 // status register along with the appropriate descriptor size indicator. 285 286 /* NOTE: To be considered... 287 * request detection interval length (for autonomous mode) 288 */ 289 290 _regs[Dma_command] = (source_increment ? Dma_source_address_increment : Dma_source_address_no_increment) | 291 (destination_increment ? Dma_destination_address_increment : Dma_destination_address_no_increment) | 292 encode_source_port_width(source_width) | 293 encode_destination_port_width(destination_width) | 294 encode_transfer_unit_size(transfer_unit_size) | 295 Dma_transfer_irq_enable; 296 297 // For a descriptor, the descriptor address would be set and the doorbell 298 // register field for the channel set. 299 300 // Enable the channel (and peripheral). 301 302 _regs[Dma_control_status] = Dma_no_descriptor_transfer | 303 Dma_channel_enable; 304 305 // Return the number of units to transfer. 306 307 return units; 308 } 309 310 unsigned int 311 Dma_x1600_channel::wait() 312 { 313 // An interrupt will occur upon completion, the completion flag will be set 314 // and the transfer count will be zero. 315 316 unsigned int remaining = 0; 317 318 do 319 { 320 if (!wait_for_irq(1000000)) 321 printf("status = %x\n", (uint32_t) _regs[Dma_control_status]); 322 else 323 { 324 printf("status = %x\n", (uint32_t) _regs[Dma_control_status]); 325 remaining = _regs[Dma_transfer_count]; 326 ack_irq(); 327 break; 328 } 329 } 330 while (!error() && !halted() && !completed()); 331 332 // Reset the channel status. 333 334 _regs[Dma_control_status] = _regs[Dma_control_status] & ~(Dma_channel_enable | 335 Dma_trans_completed | Dma_address_error | 336 Dma_trans_halted); 337 _regs[Dma_transfer_count] = 0; 338 339 // Return the number of remaining units. 340 341 return remaining; 342 } 343 344 // Wait indefinitely for an interrupt request, returning true if one was delivered. 345 346 bool 347 Dma_x1600_channel::wait_for_irq() 348 { 349 return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && _chip->have_interrupt(_channel); 350 } 351 352 // Wait up to the given timeout (in microseconds) for an interrupt request, 353 // returning true if one was delivered. 354 355 bool 356 Dma_x1600_channel::wait_for_irq(unsigned int timeout) 357 { 358 return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && _chip->have_interrupt(_channel); 359 } 360 361 // Acknowledge an interrupt condition. 362 363 void 364 Dma_x1600_channel::ack_irq() 365 { 366 _chip->ack_irq(_channel); 367 } 368 369 // Return whether a transfer has completed. 370 371 bool 372 Dma_x1600_channel::completed() 373 { 374 return _regs[Dma_control_status] & Dma_trans_completed ? true : false; 375 } 376 377 // Return whether an address error condition has arisen. 378 379 bool 380 Dma_x1600_channel::error() 381 { 382 return _chip->error() || (_regs[Dma_control_status] & Dma_address_error ? true : false); 383 } 384 385 // Return whether a transfer has halted. 386 387 bool 388 Dma_x1600_channel::halted() 389 { 390 return _chip->halted() || (_regs[Dma_control_status] & Dma_trans_halted ? true : false); 391 } 392 393 394 395 // Initialise the I2C controller. 396 397 Dma_x1600_chip::Dma_x1600_chip(l4_addr_t start, l4_addr_t end, 398 Cpm_x1600_chip *cpm) 399 : _start(start), _end(end), _cpm(cpm) 400 { 401 _regs = new Hw::Mmio_register_block<32>(start); 402 } 403 404 // Enable the peripheral. 405 406 void 407 Dma_x1600_chip::enable() 408 { 409 // Make sure that the DMA clock is available. 410 411 _cpm->start_clock(Clock_dma); 412 413 _regs[Dma_control] = Dma_control_enable; 414 while (!(_regs[Dma_control] & Dma_control_enable)); 415 } 416 417 // Disable the channel. 418 419 void 420 Dma_x1600_chip::disable() 421 { 422 _regs[Dma_control] = 0; 423 while (_regs[Dma_control] & Dma_control_enable); 424 } 425 426 // Obtain a channel object. 427 428 Dma_x1600_channel * 429 Dma_x1600_chip::get_channel(uint8_t channel, l4_cap_idx_t irq) 430 { 431 if (channel < 32) 432 return new Dma_x1600_channel(this, channel, _start + 0x20 * channel, irq); 433 else 434 throw -L4_EINVAL; 435 } 436 437 // Return whether an interrupt is pending on the given channel. 438 439 bool 440 Dma_x1600_chip::have_interrupt(uint8_t channel) 441 { 442 return _regs[Dma_irq_pending] & (1UL << channel) ? true : false; 443 } 444 445 // Acknowledge an interrupt condition on the given channel. 446 447 void 448 Dma_x1600_chip::ack_irq(uint8_t channel) 449 { 450 _regs[Dma_irq_pending] = _regs[Dma_irq_pending] & ~(1UL << channel); 451 } 452 453 // Return whether an address error condition has arisen. 454 455 bool 456 Dma_x1600_chip::error() 457 { 458 return _regs[Dma_control] & Dma_control_address_error ? true : false; 459 } 460 461 // Return whether a transfer has halted. 462 463 bool 464 Dma_x1600_chip::halted() 465 { 466 return _regs[Dma_control] & Dma_control_trans_halted ? true : false; 467 } 468 469 470 471 // C language interface functions. 472 473 void *x1600_dma_init(l4_addr_t start, l4_addr_t end, void *cpm) 474 { 475 return (void *) new Dma_x1600_chip(start, end, static_cast<Cpm_x1600_chip *>(cpm)); 476 } 477 478 void x1600_dma_disable(void *dma_chip) 479 { 480 static_cast<Dma_x1600_chip *>(dma_chip)->disable(); 481 } 482 483 void x1600_dma_enable(void *dma_chip) 484 { 485 static_cast<Dma_x1600_chip *>(dma_chip)->enable(); 486 } 487 488 void *x1600_dma_get_channel(void *dma, uint8_t channel, l4_cap_idx_t irq) 489 { 490 return static_cast<Dma_x1600_chip *>(dma)->get_channel(channel, irq); 491 } 492 493 unsigned int x1600_dma_transfer(void *dma_channel, 494 uint32_t source, uint32_t destination, 495 unsigned int count, 496 int source_increment, int destination_increment, 497 uint8_t source_width, uint8_t destination_width, 498 uint8_t transfer_unit_size, 499 enum Dma_x1600_request_type type) 500 { 501 return static_cast<Dma_x1600_channel *>(dma_channel)->transfer(source, 502 destination, count, source_increment, destination_increment, source_width, 503 destination_width, transfer_unit_size, type); 504 } 505 506 unsigned int x1600_dma_wait(void *dma_channel) 507 { 508 return static_cast<Dma_x1600_channel *>(dma_channel)->wait(); 509 }