Landfall

pkg/landfall-examples/hw_info/x1600.c

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