1 /* 2 * Perform SPI communication using the JZ4780/X1600 SPI peripheral. 3 * 4 * Copyright (C) 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/byteorder.h> 23 #include <l4/devices/dma.h> 24 #include <l4/devices/spi-common.h> 25 #include <l4/sys/err.h> 26 #include <string.h> 27 #include <stdio.h> 28 29 30 31 /* Register definitions. */ 32 33 enum Regs 34 { 35 Ssi_data = 0x00, // SSIDR 36 Ssi_control0 = 0x04, // SSICR0 37 Ssi_control1 = 0x08, // SSICR1 38 Ssi_status = 0x0c, // SSISR 39 Ssi_interval_time = 0x10, // SSIITR 40 Ssi_char_per_frame = 0x14, // SSIICR 41 Ssi_clock = 0x18, // SSICGR 42 Ssi_recv_counter = 0x1c, // SSIRCNT 43 }; 44 45 enum Ssi_data_bits : unsigned 46 { 47 Ssi_data_gpc_set = 0x10000, 48 Ssi_data_gpc_unset = 0x00000, 49 }; 50 51 enum Ssi_control0_bits : unsigned 52 { 53 Ssi_trans_endian_mask = 0xc0000, 54 Ssi_trans_endian_msbyte_msbit = 0x00000, 55 Ssi_trans_endian_msbyte_lsbit = 0x40000, 56 Ssi_trans_endian_lsbyte_lsbit = 0x80000, 57 Ssi_trans_endian_lsbyte_msbit = 0xc0000, 58 59 Ssi_recv_endian_mask = 0x30000, 60 Ssi_recv_endian_msbyte_msbit = 0x00000, 61 Ssi_recv_endian_msbyte_lsbit = 0x10000, 62 Ssi_recv_endian_lsbyte_lsbit = 0x20000, 63 Ssi_recv_endian_lsbyte_msbit = 0x30000, 64 65 Ssi_enable = 0x08000, 66 Ssi_enable_trans_half_empty = 0x04000, 67 Ssi_enable_recv_half_full = 0x02000, 68 Ssi_enable_trans_error = 0x01000, 69 Ssi_enable_recv_error = 0x00800, 70 Ssi_loopback = 0x00400, 71 Ssi_recv_finish_control = 0x00200, 72 Ssi_recv_finished = 0x00100, 73 Ssi_enable_auto_clear_underrun = 0x00080, 74 Ssi_select_pin_is_ce2 = 0x00040, 75 Ssi_use_recv_count = 0x00010, 76 Ssi_old_fifo_empty_mode = 0x00008, 77 Ssi_trans_flush = 0x00004, 78 Ssi_recv_flush = 0x00002, 79 Ssi_disable_recv = 0x00001, 80 }; 81 82 enum Ssi_control1_bits : unsigned 83 { 84 Ssi_active_mask = 0xc0000000, 85 Ssi_active_ce_low = 0x00000000, 86 Ssi_active_ce_high = 0x40000000, 87 Ssi_active_ce2_low = 0x00000000, 88 Ssi_active_ce2_high = 0x80000000, 89 90 Ssi_clock_start_delay_mask = 0x30000000, 91 Ssi_clock_start_delay_default = 0x00000000, 92 Ssi_clock_start_delay_plus_1 = 0x10000000, 93 Ssi_clock_start_delay_plus_2 = 0x20000000, 94 Ssi_clock_start_delay_plus_3 = 0x30000000, 95 96 Ssi_clock_stop_delay_mask = 0x0c000000, 97 Ssi_clock_stop_delay_default = 0x00000000, 98 Ssi_clock_stop_delay_plus_1 = 0x04000000, 99 Ssi_clock_stop_delay_plus_2 = 0x08000000, 100 Ssi_clock_stop_delay_plus_3 = 0x0c000000, 101 102 /* X1600... */ 103 104 Ssi_gpc_level_from_gpc_bit = 0x00000000, 105 Ssi_gpc_level_from_gpc_level = 0x02000000, 106 107 /* Common... */ 108 109 Ssi_interval_assert_ce_or_ce2 = 0x01000000, 110 Ssi_trans_empty_unfinished = 0x00800000, 111 112 Ssi_format_mask = 0x00300000, 113 Ssi_format_spi = 0x00000000, 114 Ssi_format_ssp = 0x00100000, 115 Ssi_format_microwire1 = 0x00200000, 116 Ssi_format_microwire2 = 0x00300000, 117 118 Ssi_trans_threshold_mask = 0x000f0000, 119 Ssi_command_length_mask = 0x0000f000, 120 Ssi_recv_threshold_mask = 0x00000f00, 121 Ssi_char_length_mask = 0x000000f8, 122 123 /* X1600... */ 124 125 Ssi_gpc_level = 0x00000004, // see Ssi_gpc_level_from_gpc_level 126 127 /* Common... */ 128 129 Spi_clock_assert_sample = 0x00000000, // phase #0 130 Spi_clock_assert_drive = 0x00000002, // phase #1 131 Spi_clock_idle_low_level = 0x00000000, // polarity #0 132 Spi_clock_idle_high_level = 0x00000001, // polarity #1 133 }; 134 135 enum Ssi_control1_shifts : unsigned 136 { 137 Ssi_trans_threshold_shift = 16, 138 Ssi_command_length_shift = 12, 139 Ssi_recv_threshold_shift = 8, 140 Ssi_char_length_shift = 3, 141 }; 142 143 enum Ssi_control1_limits : unsigned 144 { 145 Ssi_trans_threshold_limit = 15, 146 Ssi_command_length_limit = 15, 147 Ssi_recv_threshold_limit = 15, 148 Ssi_char_length_limit = 30, 149 }; 150 151 enum Ssi_status_bits : unsigned 152 { 153 Ssi_trans_char_count_mask = 0x00ff0000, 154 Ssi_recv_char_count_mask = 0x0000ff00, 155 Ssi_trans_ended = 0x00000080, 156 Ssi_trans_busy = 0x00000040, 157 Ssi_trans_fifo_full = 0x00000020, 158 Ssi_recv_fifo_empty = 0x00000010, 159 Ssi_trans_fifo_half_empty = 0x00000008, 160 Ssi_recv_fifo_half_full = 0x00000004, 161 Ssi_trans_underrun = 0x00000002, 162 Ssi_recv_overrun = 0x00000001, 163 }; 164 165 enum Ssi_status_shifts : unsigned 166 { 167 Ssi_trans_char_count_shift = 16, 168 Ssi_recv_char_count_shift = 8, 169 }; 170 171 enum Ssi_status_limits : unsigned 172 { 173 Ssi_trans_char_count_limit = 0xff, 174 Ssi_recv_char_count_limit = 0xff, 175 }; 176 177 enum Ssi_interval_time_bits : unsigned 178 { 179 Ssi_interval_clock_mask = 0x8000, 180 Ssi_interval_clock_bit_clock = 0x0000, 181 Ssi_interval_clock_32k_clock = 0x8000, 182 Ssi_interval_time_mask = 0x3fff, 183 }; 184 185 enum Ssi_char_per_frame_bits : unsigned 186 { 187 Ssi_char_per_frame_mask = 0x7, 188 }; 189 190 enum Ssi_clock_bits : unsigned 191 { 192 Ssi_clock_frequency_mask = 0xff, 193 }; 194 195 enum Ssi_recv_counter_bits : unsigned 196 { 197 Ssi_recv_counter_mask = 0xffff, 198 }; 199 200 201 202 /* Initialise a channel. */ 203 204 Spi_channel::Spi_channel(l4_addr_t spi_start, l4_addr_t start, 205 enum Clock_identifiers clock, 206 Cpm_chip *cpm, 207 Dma_channel *dma, 208 int request_type, 209 uint64_t frequency) 210 : _spi_start(spi_start), _clock(clock), _cpm(cpm), _dma(dma), 211 _request_type(request_type), _frequency(frequency) 212 { 213 _regs = new Hw::Mmio_register_block<32>(start); 214 _cpm->start_clock(clock); 215 216 /* Disable the channel while configuring: send MSB first, big endian wire 217 representation. Disable reception. */ 218 219 _regs[Ssi_control0] = Ssi_trans_endian_msbyte_msbit | 220 Ssi_select_pin_is_ce2 | 221 Ssi_disable_recv; 222 223 /* Set default transfer properties. */ 224 225 configure_transfer(8); 226 227 /* Select "normal" mode. */ 228 229 _regs[Ssi_interval_time] = 0; 230 231 /* Limit the frequency to half that of the device clock. */ 232 233 if (_frequency >= _cpm->get_frequency(_clock)) 234 _frequency = _cpm->get_frequency(_clock) / 2; 235 236 /* SSI_CLK = DEV_CLK / (2 * (divider + 1)) */ 237 238 uint32_t divider = _cpm->get_frequency(_clock) / (_frequency * 2) - 1; 239 240 _regs[Ssi_clock] = divider < Ssi_clock_frequency_mask ? divider : Ssi_clock_frequency_mask; 241 242 /* Enable the channel. */ 243 244 _regs[Ssi_control0] = _regs[Ssi_control0] | Ssi_enable; 245 } 246 247 /* NOTE: More transfer characteristics should be configurable. */ 248 249 void Spi_channel::configure_transfer(uint8_t char_size) 250 { 251 uint32_t char_length; 252 253 if (char_size < 2) 254 char_length = 0; 255 else 256 { 257 char_length = char_size - 2; 258 259 if (char_size > Ssi_char_length_limit) 260 char_length = Ssi_char_length_limit; 261 } 262 263 /* Clear the status. */ 264 265 _regs[Ssi_control0] = _regs[Ssi_control0] | Ssi_trans_flush | Ssi_recv_flush; 266 _regs[Ssi_status] = 0; 267 268 /* Indicate the desired character size. 269 270 Use active low device selection, SPI format with active low clock, with 271 data driven on the falling (asserted) clock and sampled on the rising 272 clock. */ 273 274 _regs[Ssi_control1] = (char_length << Ssi_char_length_shift) | 275 ((Ssi_trans_threshold_limit / 2) << Ssi_trans_threshold_shift) | 276 Ssi_format_spi | Ssi_active_ce2_low | 277 Spi_clock_assert_sample | Spi_clock_idle_low_level; 278 } 279 280 /* Transfer the given number of bytes from a buffer. */ 281 282 uint32_t 283 Spi_channel::send(uint32_t bytes, const uint8_t data[]) 284 { 285 return send_units(bytes, data, 1, 8, false); 286 } 287 288 /* Transfer the given number of bytes from a buffer together with control 289 values. Return the number of bytes transferred. */ 290 291 uint32_t 292 Spi_channel::send_dc(uint32_t bytes, const uint8_t data[], 293 const int dc[], uint8_t char_size, bool big_endian) 294 { 295 configure_transfer(char_size); 296 297 uint32_t transferred, char_unit; 298 uint8_t char_unit_size = ((char_size ? char_size - 1 : 0) / 8) + 1; 299 uint32_t char_mask = (1 << char_size) - 1; 300 bool last_control; 301 302 for (transferred = 0, char_unit = 0; transferred < bytes; 303 transferred += char_unit_size, char_unit++) 304 { 305 uint32_t value = get_stored_value(&data[transferred], char_unit_size, big_endian); 306 307 /* Relocate the data/command level to bit 16. */ 308 309 uint32_t command = dc[char_unit] ? Ssi_data_gpc_set : Ssi_data_gpc_unset; 310 311 /* Wait if the FIFO is full before sending. */ 312 313 while (_regs[Ssi_status] & Ssi_trans_fifo_full); 314 315 /* Combine the character with the data/command bit. */ 316 317 if (_control == NULL) 318 _regs[Ssi_data] = (value & char_mask) | command; 319 else 320 { 321 /* Set the control level after waiting for sending to complete to ensure 322 synchronisation. */ 323 324 bool this_control = dc[char_unit]; 325 326 if (transferred && (this_control != last_control)) 327 wait_busy(); 328 329 _control->acquire_control(this_control ? 1 : 0); 330 _regs[Ssi_data] = (value & char_mask); 331 last_control = this_control; 332 } 333 } 334 335 wait_busy(); 336 337 return transferred; 338 } 339 340 /* Transfer the given number of bytes from a buffer using the given unit size in 341 bytes and character size in bits. The bytes are stored in a big endian 342 arrangement. Return the number of bytes transferred. */ 343 344 uint32_t 345 Spi_channel::send_units(uint32_t bytes, const uint8_t data[], 346 uint8_t unit_size, uint8_t char_size, 347 bool big_endian) 348 { 349 configure_transfer(char_size); 350 351 uint32_t transferred; 352 uint32_t char_mask = (1 << char_size) - 1; 353 bool last_control; 354 355 for (transferred = 0; transferred < bytes; transferred += unit_size) 356 { 357 uint32_t value = get_stored_value(&data[transferred], unit_size, big_endian); 358 359 /* Relocate any command bit to bit 16 for byte characters. */ 360 361 bool data_only = unit_size * 8 == char_size; 362 bool gpc_set = (char_size < 16) && (value & (1 << char_size)); 363 uint32_t command = gpc_set ? Ssi_data_gpc_set : Ssi_data_gpc_unset; 364 365 /* Wait if the FIFO is full before sending. */ 366 367 while (_regs[Ssi_status] & Ssi_trans_fifo_full); 368 369 /* Combine the character portion of the unit with the command. */ 370 371 if (_control == NULL) 372 _regs[Ssi_data] = (value & char_mask) | command; 373 else 374 { 375 /* Set the control level after waiting for sending to complete to ensure 376 synchronisation. */ 377 378 bool this_control = gpc_set || data_only; 379 380 if (transferred && (this_control != last_control)) 381 wait_busy(); 382 383 _control->acquire_control(this_control ? 1 : 0); 384 _regs[Ssi_data] = (value & char_mask); 385 last_control = this_control; 386 } 387 } 388 389 wait_busy(); 390 391 return transferred; 392 } 393 394 /* Transfer the given number of bytes from a DMA region using the given 395 unit size in bytes and character size in bits. Return the number of bytes 396 transferred. */ 397 398 uint32_t 399 Spi_channel::transfer(l4_addr_t vaddr, 400 l4re_dma_space_dma_addr_t paddr, 401 uint32_t count, uint8_t unit_size, 402 uint8_t char_size, 403 l4_addr_t desc_vaddr, 404 l4re_dma_space_dma_addr_t desc_paddr) 405 { 406 /* Employ a non-DMA transfer if no usable physical address is provided. 407 Assume little endian byte ordering in line with the native value 408 representation. */ 409 410 if (!paddr) 411 return send_units(count, (const uint8_t *) vaddr, unit_size, char_size, 412 false); 413 414 /* Configure and initiate a DMA transfer with optional descriptor. */ 415 416 configure_transfer(char_size); 417 418 uint32_t transferred = 0; 419 uint32_t unit_count = count / unit_size; 420 uint32_t to_transfer = _dma->transfer(paddr, _spi_start + Ssi_data, 421 unit_count, true, false, 422 unit_size, unit_size, unit_size, 423 _request_type, desc_vaddr, desc_paddr); 424 425 /* Wait if not using a descriptor, which could be configured in a cycle to 426 cause an endless, repeating transfer, perhaps updating a display, for 427 example. */ 428 429 if (to_transfer && !desc_vaddr) 430 { 431 transferred = to_transfer ? (unit_count - _dma->wait()) * unit_size : 0; 432 wait_busy(); 433 } 434 else 435 transferred = to_transfer * unit_size; 436 437 return transferred; 438 } 439 440 /* Wait for the busy condition to clear or for a limited period. */ 441 442 void 443 Spi_channel::wait_busy() 444 { 445 for (unsigned int i = 0; i < (1 << 20) && (_regs[Ssi_status] & Ssi_trans_busy); i++); 446 } 447 448 449 450 /* Initialise the peripheral abstraction. */ 451 452 Spi_chip::Spi_chip(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, 453 Cpm_chip *cpm) 454 : _spi_start(spi_start), _start(start), _end(end), _cpm(cpm) 455 { 456 } 457 458 Spi_channel * 459 Spi_chip::get_channel(uint8_t channel, Dma_channel *dma, uint64_t frequency) 460 { 461 if (channel < num_channels()) 462 return _get_channel(channel, dma, frequency); 463 else 464 throw -L4_EINVAL; 465 }