1 /* 2 * DMA support for the JZ4730. 3 * 4 * Copyright (C) 2021 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-jz4730.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_irq_pending = 0xf8, // IRQP 37 Dma_control = 0xfc, // DMAC 38 }; 39 40 enum Channel_regs 41 { 42 Dma_source = 0x00, // DSA 43 Dma_destination = 0x04, // DDA 44 Dma_transfer_count = 0x08, // DTC 45 Dma_request_source = 0x0c, // DRT 46 Dma_control_status = 0x10, // DCS 47 }; 48 49 enum Dma_irq_pending_shifts : unsigned 50 { 51 Dma_irq_pending_ch0 = 15, 52 Dma_irq_pending_ch1 = 14, 53 Dma_irq_pending_ch2 = 13, 54 Dma_irq_pending_ch3 = 12, 55 Dma_irq_pending_ch4 = 11, 56 Dma_irq_pending_ch5 = 10, 57 }; 58 59 enum Dma_control_bits : unsigned 60 { 61 Dma_control_priority_mode = 0x100, // PM 62 Dma_control_halt_occurred = 0x008, // HLT 63 Dma_control_address_error = 0x004, // AR 64 Dma_control_enable = 0x001, // DMAE 65 }; 66 67 enum Dma_control_priority_modes : unsigned 68 { 69 Dma_priority_mode_01234567 = 0, 70 Dma_priority_mode_02314675 = 1, 71 Dma_priority_mode_20136457 = 2, 72 Dma_priority_mode_round_robin = 3, 73 }; 74 75 enum Dma_transfer_count_bits : unsigned 76 { 77 Dma_transfer_count_mask = 0x00ffffff, 78 }; 79 80 enum Dma_request_source_bits : unsigned 81 { 82 Dma_request_type_mask = 0x0000001f, 83 }; 84 85 enum Dma_control_status_shifts : unsigned 86 { 87 Dma_ext_output_polarity = 31, 88 Dma_ext_output_mode_cycle = 30, 89 Dma_ext_req_detect_mode = 28, 90 Dma_ext_end_of_process_mode = 27, 91 Dma_req_detect_int_length = 16, 92 Dma_source_port_width = 14, 93 Dma_dest_port_width = 12, 94 Dma_trans_unit_size = 8, 95 Dma_trans_mode = 7, 96 }; 97 98 enum Dma_control_status_bits : unsigned 99 { 100 Dma_source_address_incr = 0x00800000, 101 Dma_source_address_no_incr = 0x00000000, 102 Dma_dest_address_incr = 0x00400000, 103 Dma_dest_address_no_incr = 0x00000000, 104 105 Dma_trans_unit_size_32_bit = 0x00000000, 106 Dma_trans_unit_size_8_bit = 0x00000100, 107 Dma_trans_unit_size_16_bit = 0x00000200, 108 Dma_trans_unit_size_16_byte = 0x00000300, 109 Dma_trans_unit_size_32_byte = 0x00000400, 110 111 Dma_address_error = 0x00000010, 112 Dma_trans_completed = 0x00000008, 113 Dma_trans_halted = 0x00000004, 114 Dma_channel_irq_enable = 0x00000002, 115 Dma_channel_enable = 0x00000001, 116 }; 117 118 enum Dma_port_width_values : unsigned 119 { 120 Dma_port_width_32_bit = 0, 121 Dma_port_width_8_bit = 1, 122 Dma_port_width_16_bit = 2, 123 }; 124 125 enum Dma_trans_mode_values : unsigned 126 { 127 Dma_trans_mode_single = 0, 128 Dma_trans_mode_block = 1, 129 }; 130 131 132 133 // Initialise a channel. 134 135 Dma_jz4730_channel::Dma_jz4730_channel(Dma_jz4730_chip *chip, uint8_t channel, 136 l4_addr_t start, l4_cap_idx_t irq) 137 : _chip(chip), _channel(channel), _irq(irq) 138 { 139 _regs = new Hw::Mmio_register_block<32>(start); 140 } 141 142 // Encode flags for an external transfer. 143 144 uint32_t 145 Dma_jz4730_channel::encode_external_transfer(enum Dma_jz4730_request_type type) 146 { 147 int external = (type == Dma_request_external) ? 1 : 0; 148 149 return 150 ((external ? (int) _ext_output_polarity : 0) << Dma_ext_output_polarity) | 151 ((external ? (int) _ext_output_mode_cycle : 0) << Dma_ext_output_mode_cycle) | 152 ((external ? (int) _ext_req_detect_mode : 0) << Dma_ext_req_detect_mode) | 153 ((external ? (int) _ext_end_of_process_mode : 0) << Dma_ext_end_of_process_mode); 154 } 155 156 // Return the closest interval length greater than or equal to the number of 157 // units given encoded in the request detection interval length field of the 158 // control/status register. 159 160 uint32_t 161 Dma_jz4730_channel::encode_req_detect_int_length(uint8_t units) 162 { 163 static uint8_t lengths[] = {0, 2, 4, 8, 12, 16, 20, 24, 28, 32, 48, 60, 64, 124, 128, 200}; 164 int i; 165 166 if (!units) 167 return 0; 168 169 for (i = 0; i <= 15; i++) 170 { 171 if (lengths[i] >= units) 172 break; 173 } 174 175 return i << Dma_req_detect_int_length; 176 } 177 178 // Encode the appropriate source port width. 179 180 uint32_t 181 Dma_jz4730_channel::encode_source_port_width(uint8_t width) 182 { 183 switch (width) 184 { 185 case 1: 186 return Dma_port_width_8_bit << Dma_source_port_width; 187 188 default: 189 return Dma_port_width_32_bit << Dma_source_port_width; 190 } 191 } 192 193 // Encode the appropriate destination port width for the given request type. 194 195 uint32_t 196 Dma_jz4730_channel::encode_destination_port_width(uint8_t width) 197 { 198 switch (width) 199 { 200 case 1: 201 return Dma_port_width_8_bit << Dma_dest_port_width; 202 203 default: 204 return Dma_port_width_32_bit << Dma_dest_port_width; 205 } 206 } 207 208 // Encode the transfer unit size. 209 210 uint32_t 211 Dma_jz4730_channel::encode_transfer_unit_size(uint8_t size) 212 { 213 switch (size) 214 { 215 case 1: 216 return Dma_trans_unit_size_8_bit; 217 218 case 2: 219 return Dma_trans_unit_size_16_bit; 220 221 case 16: 222 return Dma_trans_unit_size_16_byte; 223 224 case 32: 225 return Dma_trans_unit_size_32_byte; 226 227 default: 228 return Dma_trans_unit_size_32_bit; 229 } 230 } 231 232 // Transfer data between memory locations. 233 234 unsigned int 235 Dma_jz4730_channel::transfer(uint32_t source, uint32_t destination, 236 unsigned int count, 237 bool source_increment, bool destination_increment, 238 uint8_t source_width, uint8_t destination_width, 239 uint8_t transfer_unit_size, 240 enum Dma_jz4730_request_type type) 241 { 242 // Ensure an absence of address error and halt conditions globally and in this channel. 243 244 if (error() || halted()) 245 return 0; 246 247 // Ensure an absence of transaction completed and zero transfer count for this channel. 248 249 if (completed() || _regs[Dma_transfer_count]) 250 return 0; 251 252 // Disable the channel. 253 254 _regs[Dma_control_status] = _regs[Dma_control_status] & ~Dma_channel_enable; 255 256 // Set addresses. 257 258 _regs[Dma_source] = source; 259 _regs[Dma_destination] = destination; 260 261 // Set transfer count to the number of units. 262 263 unsigned int units = count < Dma_transfer_count_mask ? count : Dma_transfer_count_mask; 264 265 _regs[Dma_transfer_count] = units; 266 267 // Set auto-request for memory-to-memory transfers. Otherwise, set the 268 // indicated request type. 269 270 _regs[Dma_request_source] = type; 271 272 // Set control/status fields. 273 // Enable the channel (and peripheral). 274 275 /* NOTE: To be considered... 276 * request detection interval length (currently left as 0) 277 * increments and port widths for external transfers 278 * port width overriding (for AIC...) 279 * transfer mode (currently left as single) 280 */ 281 282 _regs[Dma_control_status] = encode_external_transfer(type) | 283 (source_increment ? Dma_source_address_incr : Dma_source_address_no_incr) | 284 (destination_increment ? Dma_dest_address_incr : Dma_dest_address_no_incr) | 285 encode_source_port_width(source_width) | 286 encode_destination_port_width(destination_width) | 287 encode_transfer_unit_size(transfer_unit_size) | 288 (Dma_trans_mode_single << Dma_trans_mode) | 289 Dma_channel_irq_enable | 290 Dma_channel_enable; 291 292 // Return the number of units to transfer. 293 294 return units; 295 } 296 297 unsigned int 298 Dma_jz4730_channel::wait() 299 { 300 // An interrupt will occur upon completion, the completion flag will be set 301 // and the transfer count will be zero. 302 303 unsigned int remaining = 0; 304 305 do 306 { 307 if (!wait_for_irq(1000000)) 308 printf("status = %x\n", (uint32_t) _regs[Dma_control_status]); 309 310 // Clearing the completion flag will clear the interrupt condition. 311 // Any remaining units must be read before clearing the condition. 312 313 else 314 { 315 remaining = _regs[Dma_transfer_count]; 316 ack_irq(); 317 break; 318 } 319 } 320 while (!error() && !halted() && !completed()); 321 322 // Reset the channel status. 323 324 _regs[Dma_control_status] = _regs[Dma_control_status] & ~(Dma_channel_enable | 325 Dma_trans_completed | Dma_address_error | 326 Dma_trans_halted); 327 _regs[Dma_transfer_count] = 0; 328 329 // Return the number of remaining units. 330 331 return remaining; 332 } 333 334 // Wait indefinitely for an interrupt request, returning true if one was delivered. 335 336 bool 337 Dma_jz4730_channel::wait_for_irq() 338 { 339 return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && _chip->have_interrupt(_channel); 340 } 341 342 // Wait up to the given timeout (in microseconds) for an interrupt request, 343 // returning true if one was delivered. 344 345 bool 346 Dma_jz4730_channel::wait_for_irq(unsigned int timeout) 347 { 348 return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && _chip->have_interrupt(_channel); 349 } 350 351 // Acknowledge an interrupt condition. 352 353 void 354 Dma_jz4730_channel::ack_irq() 355 { 356 _regs[Dma_control_status] = _regs[Dma_control_status] & ~Dma_trans_completed; 357 } 358 359 // Return whether a transfer has completed. 360 361 bool 362 Dma_jz4730_channel::completed() 363 { 364 return _regs[Dma_control_status] & Dma_trans_completed ? true : false; 365 } 366 367 // Return whether an address error condition has arisen. 368 369 bool 370 Dma_jz4730_channel::error() 371 { 372 return _regs[Dma_control_status] & Dma_address_error ? true : false; 373 } 374 375 // Return whether a transfer has halted. 376 377 bool 378 Dma_jz4730_channel::halted() 379 { 380 return _regs[Dma_control_status] & Dma_trans_halted ? true : false; 381 } 382 383 384 385 // Initialise the I2C controller. 386 387 Dma_jz4730_chip::Dma_jz4730_chip(l4_addr_t start, l4_addr_t end, 388 Cpm_jz4730_chip *cpm) 389 : _start(start), _end(end), _cpm(cpm) 390 { 391 _regs = new Hw::Mmio_register_block<32>(start); 392 } 393 394 // Enable the peripheral. 395 396 void 397 Dma_jz4730_chip::enable() 398 { 399 // Make sure that the DMA clock is available. 400 401 _cpm->start_clock(Clock_dma); 402 403 // Enable the channel. 404 // NOTE: No configuration is done for channel priority mode. 405 406 _regs[Dma_control] = Dma_control_enable; 407 while (!(_regs[Dma_control] & Dma_control_enable)); 408 } 409 410 // Disable the channel. 411 412 void 413 Dma_jz4730_chip::disable() 414 { 415 _regs[Dma_control] = 0; 416 while (_regs[Dma_control] & Dma_control_enable); 417 } 418 419 // Obtain a channel object. 420 421 Dma_jz4730_channel * 422 Dma_jz4730_chip::get_channel(uint8_t channel, l4_cap_idx_t irq) 423 { 424 if (channel < 6) 425 return new Dma_jz4730_channel(this, channel, _start + 0x20 * channel, irq); 426 else 427 throw -L4_EINVAL; 428 } 429 430 // Return whether an interrupt is pending on the given channel. 431 432 bool 433 Dma_jz4730_chip::have_interrupt(uint8_t channel) 434 { 435 return _regs[Dma_irq_pending] & (1 << (Dma_irq_pending_ch0 - channel)) ? true : false; 436 } 437 438 439 440 // C language interface functions. 441 442 void *jz4730_dma_init(l4_addr_t start, l4_addr_t end, void *cpm) 443 { 444 return (void *) new Dma_jz4730_chip(start, end, static_cast<Cpm_jz4730_chip *>(cpm)); 445 } 446 447 void jz4730_dma_disable(void *dma_chip) 448 { 449 static_cast<Dma_jz4730_chip *>(dma_chip)->disable(); 450 } 451 452 void jz4730_dma_enable(void *dma_chip) 453 { 454 static_cast<Dma_jz4730_chip *>(dma_chip)->enable(); 455 } 456 457 void *jz4730_dma_get_channel(void *dma, uint8_t channel, l4_cap_idx_t irq) 458 { 459 return static_cast<Dma_jz4730_chip *>(dma)->get_channel(channel, irq); 460 } 461 462 void jz4730_dma_set_output_polarity(void *dma_channel, enum Dma_jz4730_ext_level polarity) 463 { 464 static_cast<Dma_jz4730_channel *>(dma_channel)->set_output_polarity(polarity); 465 } 466 467 void jz4730_dma_set_end_of_process_mode(void *dma_channel, enum Dma_jz4730_ext_level mode) 468 { 469 static_cast<Dma_jz4730_channel *>(dma_channel)->set_end_of_process_mode(mode); 470 } 471 472 void jz4730_dma_set_output_mode_cycle(void *dma_channel, enum Dma_jz4730_ext_output_mode_cycle cycle) 473 { 474 static_cast<Dma_jz4730_channel *>(dma_channel)->set_output_mode_cycle(cycle); 475 } 476 477 void jz4730_dma_set_req_detect_mode(void *dma_channel, enum Dma_jz4730_ext_req_detect_mode mode) 478 { 479 static_cast<Dma_jz4730_channel *>(dma_channel)->set_req_detect_mode(mode); 480 } 481 482 unsigned int jz4730_dma_transfer(void *dma_channel, 483 uint32_t source, uint32_t destination, 484 unsigned int count, 485 int source_increment, int destination_increment, 486 uint8_t source_width, uint8_t destination_width, 487 uint8_t transfer_unit_size, 488 enum Dma_jz4730_request_type type) 489 { 490 return static_cast<Dma_jz4730_channel *>(dma_channel)->transfer(source, 491 destination, count, source_increment, destination_increment, source_width, 492 destination_width, transfer_unit_size, type); 493 } 494 495 unsigned int jz4730_dma_wait(void *dma_channel) 496 { 497 return static_cast<Dma_jz4730_channel *>(dma_channel)->wait(); 498 }