Landfall

Annotated pkg/landfall-examples/hw_info/x1600.c

229:810ca800993b
11 months ago Paul Boddie Employ a picture representation compatible with 16-bit SPI transfers over DMA. cpm-library-improvements
paul@218 1
/*
paul@218 2
 * Access various peripherals on a board using the X1600.
paul@218 3
 *
paul@218 4
 * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
paul@218 5
 *
paul@218 6
 * This program is free software; you can redistribute it and/or
paul@218 7
 * modify it under the terms of the GNU General Public License as
paul@218 8
 * published by the Free Software Foundation; either version 2 of
paul@218 9
 * the License, or (at your option) any later version.
paul@218 10
 *
paul@218 11
 * This program is distributed in the hope that it will be useful,
paul@218 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@218 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@218 14
 * GNU General Public License for more details.
paul@218 15
 *
paul@218 16
 * You should have received a copy of the GNU General Public License
paul@218 17
 * along with this program; if not, write to the Free Software
paul@218 18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
paul@218 19
 * Boston, MA  02110-1301, USA
paul@218 20
 */
paul@218 21
paul@218 22
#include <l4/devices/aic-x1600.h>
paul@218 23
#include <l4/devices/cpm-x1600.h>
paul@218 24
#include <l4/devices/dma-x1600.h>
paul@218 25
#include <l4/devices/gpio-x1600.h>
paul@218 26
#include <l4/devices/i2c-x1600.h>
paul@218 27
#include <l4/devices/spi-gpio.h>
paul@222 28
// #include <l4/devices/spi-hybrid.h>
paul@218 29
#include "common.h"
paul@218 30
paul@218 31
paul@218 32
paul@218 33
/* AIC adapter functions. */
paul@218 34
paul@218 35
void *aic_init(l4_addr_t aic_start, l4_addr_t start, l4_addr_t end, void *cpm)
paul@218 36
{
paul@218 37
  return x1600_aic_init(aic_start, start, end, cpm);
paul@218 38
}
paul@218 39
paul@218 40
void *aic_get_channel(void *aic, int num, void *channel)
paul@218 41
{
paul@218 42
  return x1600_aic_get_channel(aic, num, channel);
paul@218 43
}
paul@218 44
paul@221 45
unsigned int aic_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
paul@221 46
                          uint32_t count, uint32_t sample_rate,
paul@221 47
                          uint8_t sample_size)
paul@218 48
{
paul@221 49
  return x1600_aic_transfer(channel, paddr, count, sample_rate, sample_size);
paul@218 50
}
paul@218 51
paul@218 52
paul@218 53
paul@218 54
/* CPM adapter functions. */
paul@218 55
paul@218 56
void *cpm_init(l4_addr_t cpm_base)
paul@218 57
{
paul@218 58
  return x1600_cpm_init(cpm_base);
paul@218 59
}
paul@218 60
paul@218 61
const char *cpm_clock_type(void *cpm, enum Clock_identifiers clock)
paul@218 62
{
paul@218 63
  return x1600_cpm_clock_type(cpm, clock);
paul@218 64
}
paul@218 65
paul@218 66
int cpm_have_clock(void *cpm, enum Clock_identifiers clock)
paul@218 67
{
paul@218 68
  return x1600_cpm_have_clock(cpm, clock);
paul@218 69
}
paul@218 70
paul@218 71
void cpm_start_clock(void *cpm, enum Clock_identifiers clock)
paul@218 72
{
paul@218 73
  x1600_cpm_start_clock(cpm, clock);
paul@218 74
}
paul@218 75
paul@218 76
void cpm_stop_clock(void *cpm, enum Clock_identifiers clock)
paul@218 77
{
paul@218 78
  x1600_cpm_stop_clock(cpm, clock);
paul@218 79
}
paul@218 80
paul@218 81
int cpm_get_parameters(void *cpm, enum Clock_identifiers clock,
paul@218 82
                       uint32_t parameters[])
paul@218 83
{
paul@218 84
  return x1600_cpm_get_parameters(cpm, clock, parameters);
paul@218 85
}
paul@218 86
paul@218 87
int cpm_set_parameters(void *cpm, enum Clock_identifiers clock,
paul@218 88
                       int num_parameters, uint32_t parameters[])
paul@218 89
{
paul@218 90
  return x1600_cpm_set_parameters(cpm, clock, num_parameters, parameters);
paul@218 91
}
paul@218 92
paul@218 93
uint8_t cpm_get_source(void *cpm, enum Clock_identifiers clock)
paul@218 94
{
paul@218 95
  return x1600_cpm_get_source(cpm, clock);
paul@218 96
}
paul@218 97
paul@218 98
void cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source)
paul@218 99
{
paul@218 100
  x1600_cpm_set_source(cpm, clock, source);
paul@218 101
}
paul@218 102
paul@218 103
enum Clock_identifiers cpm_get_source_clock(void *cpm, enum Clock_identifiers clock)
paul@218 104
{
paul@218 105
  return x1600_cpm_get_source_clock(cpm, clock);
paul@218 106
}
paul@218 107
paul@218 108
void cpm_set_source_clock(void *cpm, enum Clock_identifiers clock, enum Clock_identifiers source)
paul@218 109
{
paul@218 110
  x1600_cpm_set_source_clock(cpm, clock, source);
paul@218 111
}
paul@218 112
paul@218 113
uint64_t cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock)
paul@218 114
{
paul@218 115
  return x1600_cpm_get_source_frequency(cpm, clock);
paul@218 116
}
paul@218 117
paul@218 118
uint64_t cpm_get_frequency(void *cpm, enum Clock_identifiers clock)
paul@218 119
{
paul@218 120
  return x1600_cpm_get_frequency(cpm, clock);
paul@218 121
}
paul@218 122
paul@218 123
int cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint64_t frequency)
paul@218 124
{
paul@218 125
  return x1600_cpm_set_frequency(cpm, clock, frequency);
paul@218 126
}
paul@218 127
paul@218 128
paul@218 129
paul@218 130
/* DMA adapter functions. */
paul@218 131
paul@218 132
void *dma_init(l4_addr_t start, l4_addr_t end, void *cpm)
paul@218 133
{
paul@218 134
  return x1600_dma_init(start, end, cpm);
paul@218 135
}
paul@218 136
paul@218 137
void dma_disable(void *dma_chip)
paul@218 138
{
paul@218 139
  x1600_dma_disable(dma_chip);
paul@218 140
}
paul@218 141
paul@218 142
void dma_enable(void *dma_chip)
paul@218 143
{
paul@218 144
  x1600_dma_enable(dma_chip);
paul@218 145
}
paul@218 146
paul@218 147
void *dma_get_channel(void *dma, uint8_t channel, l4_cap_idx_t irq)
paul@218 148
{
paul@218 149
  return x1600_dma_get_channel(dma, channel, irq);
paul@218 150
}
paul@218 151
paul@218 152
unsigned int dma_transfer(void *dma_channel,
paul@218 153
                          uint32_t source, uint32_t destination,
paul@218 154
                          unsigned int count,
paul@218 155
                          int source_increment, int destination_increment,
paul@218 156
                          uint8_t source_width, uint8_t destination_width,
paul@218 157
                          uint8_t transfer_unit_size,
paul@218 158
                          int type)
paul@218 159
{
paul@218 160
  return x1600_dma_transfer(dma_channel, source, destination, count,
paul@218 161
                            source_increment, destination_increment,
paul@218 162
                            source_width, destination_width,
paul@218 163
                            transfer_unit_size, type);
paul@218 164
}
paul@218 165
paul@218 166
unsigned int dma_wait(void *dma_channel)
paul@218 167
{
paul@218 168
  return x1600_dma_wait(dma_channel);
paul@218 169
}
paul@218 170
paul@218 171
paul@218 172
paul@218 173
/* GPIO adapter functions. */
paul@218 174
paul@218 175
void *gpio_init(l4_addr_t start, l4_addr_t end, unsigned pins,
paul@218 176
                l4_uint32_t pull_ups, l4_uint32_t pull_downs)
paul@218 177
{
paul@218 178
  return x1600_gpio_init(start, end, pins, pull_ups, pull_downs);
paul@218 179
}
paul@218 180
paul@218 181
void gpio_setup(void *gpio, unsigned pin, unsigned mode, int value)
paul@218 182
{
paul@218 183
  x1600_gpio_setup(gpio, pin, mode, value);
paul@218 184
}
paul@218 185
paul@218 186
void gpio_config_pull(void *gpio, unsigned pin, unsigned mode)
paul@218 187
{
paul@218 188
  x1600_gpio_config_pull(gpio, pin, mode);
paul@218 189
}
paul@218 190
paul@218 191
void gpio_config_pad(void *gpio, unsigned pin, unsigned func, unsigned value)
paul@218 192
{
paul@218 193
  x1600_gpio_config_pad(gpio, pin, func, value);
paul@218 194
}
paul@218 195
paul@218 196
void gpio_config_get(void *gpio, unsigned pin, unsigned reg, unsigned *value)
paul@218 197
{
paul@218 198
  x1600_gpio_config_get(gpio, pin, reg, value);
paul@218 199
}
paul@218 200
paul@218 201
void gpio_config_pad_get(void *gpio, unsigned pin, unsigned *func, unsigned *value)
paul@218 202
{
paul@218 203
  x1600_gpio_config_pad_get(gpio, pin, func, value);
paul@218 204
}
paul@218 205
paul@218 206
void gpio_multi_setup(void *gpio, Pin_slice const *mask, unsigned mode, unsigned outvalues)
paul@218 207
{
paul@218 208
  x1600_gpio_multi_setup(gpio, mask, mode, outvalues);
paul@218 209
}
paul@218 210
paul@218 211
void gpio_multi_config_pad(void *gpio, Pin_slice const *mask, unsigned func, unsigned value)
paul@218 212
{
paul@218 213
  x1600_gpio_multi_config_pad(gpio, mask, func, value);
paul@218 214
}
paul@218 215
paul@218 216
void gpio_multi_set(void *gpio, Pin_slice const *mask, unsigned data)
paul@218 217
{
paul@218 218
  x1600_gpio_multi_set(gpio, mask, data);
paul@218 219
}
paul@218 220
paul@218 221
unsigned gpio_multi_get(void *gpio, unsigned offset)
paul@218 222
{
paul@218 223
  return x1600_gpio_multi_get(gpio, offset);
paul@218 224
}
paul@218 225
paul@218 226
int gpio_get(void *gpio, unsigned pin)
paul@218 227
{
paul@218 228
  return x1600_gpio_get(gpio, pin);
paul@218 229
}
paul@218 230
paul@218 231
void gpio_set(void *gpio, unsigned pin, int value)
paul@218 232
{
paul@218 233
  x1600_gpio_set(gpio, pin, value);
paul@218 234
}
paul@218 235
paul@218 236
void *gpio_get_irq(void *gpio, unsigned pin)
paul@218 237
{
paul@218 238
  return x1600_gpio_get_irq(gpio, pin);
paul@218 239
}
paul@218 240
paul@218 241
bool gpio_irq_set_mode(void *gpio_irq, unsigned mode)
paul@218 242
{
paul@218 243
  return x1600_gpio_irq_set_mode(gpio_irq, mode);
paul@218 244
}
paul@218 245
paul@218 246
paul@218 247
paul@218 248
/* I2C adapter functions. */
paul@218 249
paul@218 250
void *i2c_init(l4_addr_t start, l4_addr_t end, void *cpm,
paul@218 251
                uint32_t frequency)
paul@218 252
{
paul@218 253
  return x1600_i2c_init(start, end, cpm, frequency);
paul@218 254
}
paul@218 255
paul@218 256
void *i2c_get_channel(void *i2c, uint8_t channel)
paul@218 257
{
paul@218 258
  return x1600_i2c_get_channel(i2c, channel);
paul@218 259
}
paul@218 260
paul@218 261
uint32_t i2c_get_frequency(void *i2c_channel)
paul@218 262
{
paul@218 263
  return x1600_i2c_get_frequency(i2c_channel);
paul@218 264
}
paul@218 265
paul@218 266
void i2c_set_target(void *i2c_channel, uint8_t addr)
paul@218 267
{
paul@218 268
  return x1600_i2c_set_target(i2c_channel, addr);
paul@218 269
}
paul@218 270
paul@218 271
void i2c_start_read(void *i2c_channel, uint8_t buf[], unsigned int total,
paul@218 272
                    int stop)
paul@218 273
{
paul@218 274
  x1600_i2c_start_read(i2c_channel, buf, total, stop);
paul@218 275
}
paul@218 276
paul@218 277
void i2c_read(void *i2c_channel)
paul@218 278
{
paul@218 279
  x1600_i2c_read(i2c_channel);
paul@218 280
}
paul@218 281
paul@218 282
void i2c_start_write(void *i2c_channel, uint8_t buf[], unsigned int total,
paul@218 283
                     int stop)
paul@218 284
{
paul@218 285
  x1600_i2c_start_write(i2c_channel, buf, total, stop);
paul@218 286
}
paul@218 287
paul@218 288
void i2c_write(void *i2c_channel)
paul@218 289
{
paul@218 290
  x1600_i2c_write(i2c_channel);
paul@218 291
}
paul@218 292
paul@218 293
int i2c_read_done(void *i2c_channel)
paul@218 294
{
paul@218 295
  return x1600_i2c_read_done(i2c_channel);
paul@218 296
}
paul@218 297
paul@218 298
int i2c_write_done(void *i2c_channel)
paul@218 299
{
paul@218 300
  return x1600_i2c_write_done(i2c_channel);
paul@218 301
}
paul@218 302
paul@218 303
unsigned int i2c_have_read(void *i2c_channel)
paul@218 304
{
paul@218 305
  return x1600_i2c_have_read(i2c_channel);
paul@218 306
}
paul@218 307
paul@218 308
unsigned int i2c_have_written(void *i2c_channel)
paul@218 309
{
paul@218 310
  return x1600_i2c_have_written(i2c_channel);
paul@218 311
}
paul@218 312
paul@218 313
int i2c_failed(void *i2c_channel)
paul@218 314
{
paul@218 315
  return x1600_i2c_failed(i2c_channel);
paul@218 316
}
paul@218 317
paul@218 318
void i2c_stop(void *i2c_channel)
paul@218 319
{
paul@218 320
  x1600_i2c_stop(i2c_channel);
paul@218 321
}
paul@218 322
paul@218 323
paul@218 324
paul@218 325
/* SPI adapter functions. */
paul@218 326
paul@221 327
void *spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, void *cpm)
paul@221 328
{
paul@221 329
  (void) spi_start; (void) start; (void) end; (void) cpm;
paul@221 330
  return NULL;
paul@221 331
}
paul@221 332
paul@222 333
void *spi_get_channel(void *spi, uint8_t num, void *channel, uint64_t frequency,
paul@222 334
                      void *control_chip, int control_pin, int control_alt_func)
paul@221 335
{
paul@222 336
  /* NOTE: Initialisation of a hybrid channel to be supported. */
paul@222 337
paul@221 338
  (void) spi; (void) num; (void) channel; (void) frequency;
paul@222 339
  (void) control_chip; (void) control_pin; (void) control_alt_func;
paul@221 340
  return NULL;
paul@221 341
}
paul@221 342
paul@222 343
void *spi_get_channel_gpio(uint64_t frequency,
paul@222 344
                           void *clock_chip, int clock_pin,
paul@221 345
                           void *data_chip, int data_pin,
paul@221 346
                           void *enable_chip, int enable_pin,
paul@222 347
                           void *control_chip, int control_pin)
paul@218 348
{
paul@222 349
  return spi_gpio_get_channel(frequency, clock_chip, clock_pin, data_chip,
paul@222 350
                              data_pin, enable_chip, enable_pin, control_chip,
paul@222 351
                              control_pin);
paul@222 352
}
paul@222 353
paul@222 354
void spi_acquire_control(void *channel, int level)
paul@222 355
{
paul@222 356
  /* NOTE: Not yet supported. */
paul@222 357
paul@222 358
  (void) channel; (void) level;
paul@222 359
  // spi_hybrid_acquire_control(channel, level);
paul@218 360
}
paul@218 361
paul@222 362
void spi_release_control(void *channel)
paul@222 363
{
paul@222 364
  /* NOTE: Not yet supported. */
paul@222 365
paul@222 366
  (void) channel;
paul@222 367
  // spi_hybrid_release_control(channel);
paul@222 368
}
paul@222 369
paul@222 370
void spi_send_gpio(void *channel, uint32_t bytes, const uint8_t data[])
paul@222 371
{
paul@222 372
  spi_gpio_send(channel, bytes, data);
paul@222 373
}
paul@222 374
paul@222 375
void spi_send_units(void *channel, uint32_t bytes, const uint8_t data[], uint8_t unit_size,
paul@222 376
                    uint8_t char_size)
paul@221 377
{
paul@221 378
  /* NOTE: Not yet supported. */
paul@221 379
paul@221 380
  (void) channel; (void) bytes; (void) data; (void) unit_size; (void) char_size;
paul@222 381
  // x1600_spi_send_units(channel, bytes, data, unit_size, char_size);
paul@218 382
}
paul@218 383
paul@221 384
uint32_t spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
paul@223 385
                      uint32_t count, uint8_t unit_size, uint8_t char_size,
paul@223 386
                      l4_addr_t desc_vaddr, l4re_dma_space_dma_addr_t desc_paddr)
paul@221 387
{
paul@221 388
  /* NOTE: Not yet supported. */
paul@221 389
paul@221 390
  (void) channel; (void) paddr; (void) count; (void) unit_size; (void) char_size;
paul@223 391
  (void) desc_vaddr; (void) desc_paddr;
paul@223 392
  // return x1600_spi_transfer(channel, paddr, count, unit_size, char_size,
paul@223 393
  //                           desc_vaddr, desc_paddr);
paul@221 394
  return 0;
paul@221 395
}
paul@221 396
paul@218 397
paul@218 398
paul@218 399
/* Memory regions. */
paul@218 400
paul@218 401
const char *memory_regions[] = {
paul@218 402
  [AIC] = "x1600-aic",
paul@218 403
  [CPM] = "x1600-cpm",
paul@218 404
  [DMA] = "x1600-dma",
paul@218 405
  [GPIO] = "x1600-gpio",
paul@218 406
  [I2C] = "x1600-i2c",
paul@221 407
  [SSI] = "x1600-ssi",
paul@218 408
};
paul@218 409
paul@218 410
paul@218 411
paul@218 412
/* AIC definitions. */
paul@218 413
paul@218 414
void *aic_channels[] = {NULL};
paul@218 415
paul@218 416
const unsigned int num_aic_channels = 1;
paul@218 417
paul@218 418
l4_cap_idx_t aic_irqs[] = {L4_INVALID_CAP};
paul@218 419
paul@218 420
paul@218 421
paul@218 422
/* CPM definitions. */
paul@218 423
paul@218 424
struct clock_info clocks[] = {
paul@218 425
  {"ext",   Clock_external, "External"},
paul@218 426
  {"plla",  Clock_pll_A, "PLL A"},
paul@218 427
  {"plle",  Clock_pll_E, "PLL E"},
paul@218 428
  {"pllm",  Clock_pll_M, "PLL M"},
paul@218 429
  {"main",  Clock_main, "Main"},
paul@218 430
  {"cpu",   Clock_cpu, "CPU"},
paul@218 431
  {"ahb0",  Clock_hclock0, "AHB0"},
paul@218 432
  {"ahb2",  Clock_hclock2, "AHB2"},
paul@218 433
  {"apb",   Clock_pclock, "APB"},
paul@218 434
  {"aic",   Clock_aic, "AIC"},
paul@218 435
  {"dma",   Clock_dma, "DMA"},
paul@221 436
  {"lcd0",  Clock_lcd_pixel0, "LCD pixel"},
paul@218 437
  {"msc0",  Clock_msc0, "MSC0"},
paul@218 438
  {"msc1",  Clock_msc1, "MSC1"},
paul@218 439
  {"otg",   Clock_otg0, "USB OTG"},
paul@218 440
  {"i2c0",  Clock_i2c0, "I2C0"},
paul@218 441
  {"i2c1",  Clock_i2c1, "I2C1"},
paul@218 442
  {"i2s0",  Clock_i2s0, "I2S0"},
paul@218 443
  {"i2s1",  Clock_i2s1, "I2S1"},
paul@218 444
  {"i2s0r", Clock_i2s0_rx, "I2S0 RX"},
paul@218 445
  {"i2s0t", Clock_i2s0_tx, "I2S0 TX"},
paul@221 446
  {"ssi0",  Clock_ssi0, "SSI"},
paul@218 447
  {"uart0", Clock_uart0, "UART0"},
paul@218 448
  {"uart1", Clock_uart1, "UART1"},
paul@218 449
  {"uart2", Clock_uart2, "UART2"},
paul@218 450
  {"uart3", Clock_uart3, "UART3"},
paul@218 451
  {NULL,    Clock_undefined, NULL},
paul@218 452
};
paul@218 453
paul@218 454
paul@218 455
paul@218 456
/* DMA definitions. */
paul@218 457
paul@218 458
void *dma_channels[32] = {NULL};
paul@218 459
paul@218 460
const unsigned int num_dma_channels = 32;
paul@218 461
paul@221 462
struct dma_region dma_regions[8];
paul@218 463
paul@221 464
const unsigned int num_dma_regions = 8;
paul@218 465
paul@218 466
l4_cap_idx_t dma_irq = L4_INVALID_CAP;
paul@218 467
paul@218 468
paul@218 469
paul@218 470
/* GPIO definitions. */
paul@218 471
paul@218 472
struct gpio_port gpio_ports[] = {
paul@218 473
  {0xffffffff, 0x00000000},
paul@218 474
  {0xdffbf7bf, 0x00000000},
paul@218 475
  {0x987e0000, 0x07000007},
paul@218 476
  {0x0000003f, 0x00000000}
paul@218 477
};
paul@218 478
paul@218 479
const unsigned int num_gpio_ports = 4;
paul@218 480
paul@218 481
const char gpio_port_labels[] = "ABCD";
paul@218 482
paul@218 483
paul@218 484
paul@218 485
/* I2C definitions. */
paul@218 486
paul@218 487
void *i2c_channels[] = {NULL, NULL};
paul@218 488
paul@218 489
const unsigned int num_i2c_channels = 2;
paul@218 490
paul@218 491
l4_cap_idx_t i2c_irqs[] = {L4_INVALID_CAP, L4_INVALID_CAP};
paul@218 492
paul@218 493
paul@218 494
paul@218 495
/* SPI definitions. */
paul@218 496
paul@218 497
void *spi_channels[] = {NULL};
paul@218 498
paul@218 499
const unsigned int num_spi_channels = 1;