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/cpm-x1600.h> 23 #include <l4/devices/dma-x1600.h> 24 #include <l4/devices/hw_mmio_register_block.h> 25 26 #include <l4/sys/cache.h> 27 #include <l4/sys/ipc.h> 28 #include <l4/sys/irq.h> 29 #include <l4/sys/rcv_endpoint.h> 30 #include <l4/util/util.h> 31 32 #include <systypes/thread.h> 33 34 #include <stdio.h> 35 36 37 38 enum Global_regs 39 { 40 Dma_control = 0x1000, // DMAC 41 Dma_irq_pending = 0x1004, // DIRQP 42 Dma_doorbell = 0x1008, // DDB 43 Dma_doorbell_set = 0x100c, // DDS 44 }; 45 46 enum Channel_regs 47 { 48 Dma_source = 0x00, // DSA 49 Dma_destination = 0x04, // DTA 50 Dma_transfer_count = 0x08, // DTC 51 Dma_request_source = 0x0c, // DRT 52 Dma_control_status = 0x10, // DCS 53 Dma_command = 0x14, // DCM 54 Dma_descriptor_address = 0x18, // DDA 55 Dma_stride = 0x1c, // DSD 56 }; 57 58 enum Dma_control_bits : unsigned 59 { 60 Dma_fast_msc_transfer = 0x80000000, // FMSC 61 Dma_fast_ssi_transfer = 0x40000000, // FSSI 62 Dma_fast_tssi_transfer = 0x20000000, // FTSSI 63 Dma_fast_uart_transfer = 0x10000000, // FUART 64 Dma_fast_aic_transfer = 0x08000000, // FAIC 65 Dma_control_trans_halted = 0x00000008, // HLT 66 Dma_control_address_error = 0x00000004, // AR 67 Dma_control_enable = 0x00000001, // DMAE 68 }; 69 70 enum Dma_transfer_count_bits : unsigned 71 { 72 Dma_descriptor_offset_mask = 0xff000000, // DOA (in DES3) 73 74 Dma_transfer_count_mask = 0x00ffffff, 75 Dma_descriptor_offset_shift = 24, 76 }; 77 78 enum Dma_request_source_bits : unsigned 79 { 80 Dma_request_type_mask = 0x0000003f, 81 }; 82 83 enum Dma_control_status_bits : unsigned 84 { 85 Dma_no_descriptor_transfer = 0x80000000, 86 Dma_8word_descriptor = 0x40000000, 87 Dma_copy_offset_mask = 0x0000ff00, 88 Dma_address_error = 0x00000010, 89 Dma_trans_completed = 0x00000008, 90 Dma_trans_halted = 0x00000004, 91 Dma_channel_enable = 0x00000001, 92 93 Dma_copy_offset_shift = 8, 94 }; 95 96 enum Dma_command_bits : unsigned 97 { 98 Dma_source_address_increment = 0x800000, 99 Dma_source_address_no_increment = 0x000000, 100 Dma_destination_address_increment = 0x400000, 101 Dma_destination_address_no_increment = 0x000000, 102 103 Dma_source_address_increment_wrap = 0x200000, 104 Dma_destination_address_increment_wrap = 0x100000, 105 Dma_recommended_data_unit_size_mask = 0x0f0000, 106 Dma_source_port_width_mask = 0x00c000, 107 Dma_destination_port_width_mask = 0x003000, 108 Dma_transfer_unit_size_mask = 0x000f00, 109 110 Dma_trans_unit_size_32_bit = 0x000000, 111 Dma_trans_unit_size_8_bit = 0x000100, 112 Dma_trans_unit_size_16_bit = 0x000200, 113 Dma_trans_unit_size_16_byte = 0x000300, 114 Dma_trans_unit_size_32_byte = 0x000400, 115 Dma_trans_unit_size_64_byte = 0x000500, 116 Dma_trans_unit_size_128_byte = 0x000600, 117 Dma_trans_unit_size_autonomous = 0x000700, 118 Dma_trans_unit_size_external = 0x000800, 119 120 Dma_source_address_compare_index = 0x000080, 121 Dma_destination_address_compare_index = 0x000040, 122 Dma_stride_enable = 0x000004, 123 Dma_transfer_irq_enable = 0x000002, 124 Dma_descriptor_link_enable = 0x000001, 125 126 Dma_recommended_data_unit_size_shift = 16, 127 Dma_source_port_width_shift = 14, 128 Dma_destination_port_width_shift = 12, 129 Dma_transfer_unit_size_shift = 8, 130 }; 131 132 enum Dma_port_width_values : unsigned 133 { 134 Dma_port_width_32_bit = 0, 135 Dma_port_width_8_bit = 1, 136 Dma_port_width_16_bit = 2, 137 }; 138 139 140 141 // Initialise a channel. 142 143 Dma_x1600_channel::Dma_x1600_channel(Dma_chip *chip, uint8_t channel, 144 l4_addr_t start, l4_cap_idx_t irq) 145 : _chip(chip), _channel(channel), _irq(irq) 146 { 147 _regs = new Hw::Mmio_register_block<32>(start); 148 149 // Initialise the transfer count. 150 151 _regs[Dma_transfer_count] = 0; 152 } 153 154 // Return the closest interval length greater than or equal to the number of 155 // units given encoded in the request detection interval length field of the 156 // control/status register. 157 158 uint32_t 159 Dma_x1600_channel::encode_req_detect_int_length(uint8_t units) 160 { 161 static uint8_t lengths[] = {0, 1, 2, 3, 4, 8, 16, 32, 64, 128}; 162 int i; 163 164 if (!units) 165 return 0; 166 167 for (i = 0; i <= 9; i++) 168 { 169 if (lengths[i] >= units) 170 break; 171 } 172 173 return i << Dma_recommended_data_unit_size_shift; 174 } 175 176 // Encode the appropriate source port width for the given request type. 177 178 uint32_t 179 Dma_x1600_channel::encode_source_port_width(uint8_t width) 180 { 181 switch (width) 182 { 183 case 1: 184 return Dma_port_width_8_bit << Dma_source_port_width_shift; 185 186 case 2: 187 return Dma_port_width_16_bit << Dma_source_port_width_shift; 188 189 default: 190 return Dma_port_width_32_bit << Dma_source_port_width_shift; 191 } 192 } 193 194 // Encode the appropriate destination port width for the given request type. 195 196 uint32_t 197 Dma_x1600_channel::encode_destination_port_width(uint8_t width) 198 { 199 switch (width) 200 { 201 case 1: 202 return Dma_port_width_8_bit << Dma_destination_port_width_shift; 203 204 case 2: 205 return Dma_port_width_16_bit << Dma_destination_port_width_shift; 206 207 default: 208 return Dma_port_width_32_bit << Dma_destination_port_width_shift; 209 } 210 } 211 212 // Encode the transfer unit size. 213 // NOTE: This does not handle the external case. 214 215 uint32_t 216 Dma_x1600_channel::encode_transfer_unit_size(uint8_t size) 217 { 218 switch (size) 219 { 220 case 0: 221 return Dma_trans_unit_size_autonomous; 222 223 case 1: 224 return Dma_trans_unit_size_8_bit; 225 226 case 2: 227 return Dma_trans_unit_size_16_bit; 228 229 case 16: 230 return Dma_trans_unit_size_16_byte; 231 232 case 32: 233 return Dma_trans_unit_size_32_byte; 234 235 case 64: 236 return Dma_trans_unit_size_64_byte; 237 238 case 128: 239 return Dma_trans_unit_size_128_byte; 240 241 default: 242 return Dma_trans_unit_size_32_bit; 243 } 244 } 245 246 // Transfer data between memory locations, returning the number of units that 247 // should have been transferred. 248 249 unsigned int 250 Dma_x1600_channel::transfer(uint32_t source, uint32_t destination, 251 unsigned int count, 252 bool source_increment, bool destination_increment, 253 uint8_t source_width, uint8_t destination_width, 254 uint8_t transfer_unit_size, 255 int type, 256 l4_addr_t desc_vaddr, 257 l4re_dma_space_dma_addr_t desc_paddr) 258 { 259 // Ensure an absence of address error and halt conditions globally and in this channel. 260 261 if (error() || halted()) 262 { 263 printf("Cleared:%s%s\n", error() ? " error" : "", halted() ? " halted" : ""); 264 clear_errors(); 265 } 266 267 // Ensure a zero transfer count for this channel. 268 269 if (_regs[Dma_transfer_count]) 270 return 0; 271 272 // Disable the channel. 273 274 _regs[Dma_control_status] = _regs[Dma_control_status] & ~Dma_channel_enable; 275 276 // Set transfer count to the number of units. 277 278 unsigned int units = count < Dma_transfer_count_mask ? count : Dma_transfer_count_mask; 279 280 // NOTE: Request detection interval length (for autonomous mode) not considered. 281 282 uint32_t command = (source_increment ? Dma_source_address_increment 283 : Dma_source_address_no_increment) | 284 (destination_increment ? Dma_destination_address_increment 285 : Dma_destination_address_no_increment) | 286 encode_source_port_width(source_width) | 287 encode_destination_port_width(destination_width) | 288 encode_transfer_unit_size(transfer_unit_size) | 289 Dma_transfer_irq_enable; 290 291 // Populate the descriptor, largely corresponding to the population of 292 // registers when descriptors are not being used. 293 294 if (desc_vaddr) 295 { 296 // For a descriptor, the descriptor address would be set and the doorbell 297 // register field for the channel set. 298 299 // For a descriptor, the actual fields would be populated instead of the 300 // command register, descriptor transfer would be indicated in the control/ 301 // status register along with the appropriate descriptor size indicator. 302 303 struct x1600_dma_descriptor *desc = (struct x1600_dma_descriptor *) desc_vaddr; 304 305 // NOTE: Linking to the same descriptor. 306 307 uint32_t descriptor_offset = 0; 308 309 desc->command = command | Dma_descriptor_link_enable; 310 desc->source = source; 311 desc->destination = destination; 312 desc->transfer_count = (units & Dma_transfer_count_mask) | 313 (descriptor_offset << Dma_descriptor_offset_shift); 314 desc->request_source = (enum Dma_x1600_request_type) type; 315 316 // NOTE: Stride not supported yet. 317 318 l4_cache_clean_data((unsigned long) desc_vaddr, 319 (unsigned long) desc_vaddr + sizeof(*desc)); 320 321 // Commit the descriptor. 322 323 _regs[Dma_descriptor_address] = desc_paddr; 324 _chip->commit_descriptor(_channel); 325 } 326 327 // Otherwise, populate the registers for a one-off transfer. 328 329 else 330 { 331 // Set addresses and transfer count. 332 333 _regs[Dma_source] = source; 334 _regs[Dma_destination] = destination; 335 _regs[Dma_transfer_count] = units; 336 _regs[Dma_request_source] = (enum Dma_x1600_request_type) type; 337 _regs[Dma_command] = command; 338 } 339 340 // Enable the channel with descriptor transfer configured if appropriate. 341 342 _regs[Dma_control_status] = (desc_vaddr ? Dma_8word_descriptor : 343 Dma_no_descriptor_transfer) | 344 Dma_channel_enable; 345 346 // Return the number of units to transfer. 347 348 return units; 349 } 350 351 // Wait for a transfer to end, returning the number of units remaining to be 352 // transferred. 353 354 unsigned int 355 Dma_x1600_channel::wait() 356 { 357 // An interrupt will occur upon completion, the completion flag will be set 358 // and the transfer count will be zero. 359 360 unsigned int remaining = 0; 361 362 do 363 { 364 if (!wait_for_irq(1000000)) 365 printf("status = %x\n", (uint32_t) _regs[Dma_control_status]); 366 else 367 { 368 remaining = _regs[Dma_transfer_count]; 369 ack_irq(); 370 break; 371 } 372 } 373 while (!error() && !halted() && !completed()); 374 375 // Reset the channel status. 376 377 _regs[Dma_control_status] = _regs[Dma_control_status] & ~(Dma_channel_enable | 378 Dma_trans_completed | Dma_address_error | 379 Dma_trans_halted); 380 _regs[Dma_transfer_count] = 0; 381 382 return remaining; 383 } 384 385 // Wait indefinitely for an interrupt request, returning true if one was delivered. 386 387 bool 388 Dma_x1600_channel::wait_for_irq() 389 { 390 if (l4_error(l4_rcv_ep_bind_thread(_irq, get_current_thread(), 0))) 391 return false; 392 393 return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && _chip->have_interrupt(_channel); 394 } 395 396 // Wait up to the given timeout (in microseconds) for an interrupt request, 397 // returning true if one was delivered. 398 399 bool 400 Dma_x1600_channel::wait_for_irq(unsigned int timeout) 401 { 402 if (l4_error(l4_rcv_ep_bind_thread(_irq, get_current_thread(), 0))) 403 return false; 404 405 return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && _chip->have_interrupt(_channel); 406 } 407 408 // Acknowledge an interrupt condition. 409 410 void 411 Dma_x1600_channel::ack_irq() 412 { 413 _chip->ack_irq(_channel); 414 } 415 416 // Clear error conditions. 417 418 void 419 Dma_x1600_channel::clear_errors() 420 { 421 _regs[Dma_control_status] = _regs[Dma_control_status] & ~(Dma_address_error | Dma_trans_halted); 422 _chip->clear_errors(); 423 } 424 425 // Return whether a transfer has completed. 426 427 bool 428 Dma_x1600_channel::completed() 429 { 430 return _regs[Dma_control_status] & Dma_trans_completed ? true : false; 431 } 432 433 // Return whether an address error condition has arisen. 434 435 bool 436 Dma_x1600_channel::error() 437 { 438 return _chip->error() || (_regs[Dma_control_status] & Dma_address_error ? true : false); 439 } 440 441 // Return whether a transfer has halted. 442 443 bool 444 Dma_x1600_channel::halted() 445 { 446 return _chip->halted() || (_regs[Dma_control_status] & Dma_trans_halted ? true : false); 447 } 448 449 450 451 // Initialise the I2C controller. 452 453 Dma_x1600_chip::Dma_x1600_chip(l4_addr_t start, l4_addr_t end, Cpm_chip *cpm) 454 : _start(start), _end(end), _cpm(cpm) 455 { 456 _regs = new Hw::Mmio_register_block<32>(start); 457 } 458 459 // Enable the peripheral. 460 461 void 462 Dma_x1600_chip::enable() 463 { 464 // Make sure that the DMA clock is available. 465 466 _cpm->start_clock(Clock_dma); 467 468 _regs[Dma_control] = Dma_control_enable; 469 while (!(_regs[Dma_control] & Dma_control_enable)); 470 } 471 472 // Disable the channel. 473 474 void 475 Dma_x1600_chip::disable() 476 { 477 _regs[Dma_control] = 0; 478 while (_regs[Dma_control] & Dma_control_enable); 479 } 480 481 // Obtain a channel object. 482 483 Dma_channel * 484 Dma_x1600_chip::get_channel(uint8_t channel, l4_cap_idx_t irq) 485 { 486 if (channel < 32) 487 return new Dma_x1600_channel(this, channel, _start + 0x20 * channel, irq); 488 else 489 throw -L4_EINVAL; 490 } 491 492 // Return whether an interrupt is pending on the given channel. 493 494 bool 495 Dma_x1600_chip::have_interrupt(uint8_t channel) 496 { 497 return _regs[Dma_irq_pending] & (1UL << channel) ? true : false; 498 } 499 500 // Acknowledge an interrupt condition on the given channel. 501 502 void 503 Dma_x1600_chip::ack_irq(uint8_t channel) 504 { 505 _regs[Dma_irq_pending] = _regs[Dma_irq_pending] & ~(1UL << channel); 506 } 507 508 // Clear error conditions. 509 510 void 511 Dma_x1600_chip::clear_errors() 512 { 513 _regs[Dma_control] = _regs[Dma_control] & ~(Dma_control_address_error | Dma_control_trans_halted); 514 } 515 516 // Return whether an address error condition has arisen. 517 518 bool 519 Dma_x1600_chip::error() 520 { 521 return _regs[Dma_control] & Dma_control_address_error ? true : false; 522 } 523 524 // Return whether a transfer has halted. 525 526 bool 527 Dma_x1600_chip::halted() 528 { 529 return _regs[Dma_control] & Dma_control_trans_halted ? true : false; 530 } 531 532 void 533 Dma_x1600_chip::commit_descriptor(uint8_t channel) 534 { 535 _regs[Dma_doorbell_set] = (1 << channel); 536 } 537 538 Dma_chip *x1600_dma_chip(l4_addr_t start, l4_addr_t end, Cpm_chip *cpm) 539 { 540 return new Dma_x1600_chip(start, end, cpm); 541 } 542 543 544 545 // C language interface functions. 546 547 void *x1600_dma_init(l4_addr_t start, l4_addr_t end, void *cpm) 548 { 549 return (void *) x1600_dma_chip(start, end, static_cast<Cpm_chip *>(cpm)); 550 } 551 552 void x1600_dma_disable(void *dma_chip) 553 { 554 static_cast<Dma_chip *>(dma_chip)->disable(); 555 } 556 557 void x1600_dma_enable(void *dma_chip) 558 { 559 static_cast<Dma_chip *>(dma_chip)->enable(); 560 } 561 562 void *x1600_dma_get_channel(void *dma, uint8_t channel, l4_cap_idx_t irq) 563 { 564 return static_cast<Dma_chip *>(dma)->get_channel(channel, irq); 565 } 566 567 unsigned int x1600_dma_transfer(void *dma_channel, 568 uint32_t source, uint32_t destination, 569 unsigned int count, 570 int source_increment, int destination_increment, 571 uint8_t source_width, uint8_t destination_width, 572 uint8_t transfer_unit_size, 573 enum Dma_x1600_request_type type) 574 { 575 return static_cast<Dma_x1600_channel *>(dma_channel)->transfer(source, 576 destination, count, source_increment, destination_increment, source_width, 577 destination_width, transfer_unit_size, type); 578 } 579 580 unsigned int x1600_dma_wait(void *dma_channel) 581 { 582 return static_cast<Dma_x1600_channel *>(dma_channel)->wait(); 583 }