Landfall

pkg/landfall-examples/hw_info/jz4780.c

243:c705336ff600
11 months ago Paul Boddie Introduced internal/chip-specific clock identifiers, starting with USB PHY source clocks. Replaced Clock_undefined with Clock_none, adjusting the clock identifier ordering. cpm-library-improvements
     1 /*     2  * Access various peripherals on a board using the JZ4780.     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 /* NOTE: AIC support should be replaced. The CI20 should be able to send I2S    23          audio over HDMI or via its internal codec to the headphone socket. */    24     25 #include <l4/devices/aic-x1600.h>    26     27 #include <l4/devices/cpm-jz4780.h>    28 #include <l4/devices/dma-jz4780.h>    29 #include <l4/devices/gpio-jz4780.h>    30 #include <l4/devices/i2c-jz4780.h>    31     32 /* The X1600 RTC functionality is a subset of that in the JZ4780. */    33     34 #include <l4/devices/rtc-x1600.h>    35     36 /* GPIO-based SPI can use arbitrary pins, whereas on the CI20 only the secondary    37    header provides pins like GPC. */    38     39 #include <l4/devices/spi-gpio.h>    40 #include <l4/devices/spi-hybrid.h>    41 #include <l4/devices/spi-jz4780.h>    42 #include "common.h"    43     44     45     46 /* AIC adapter functions. */    47     48 void *aic_init(l4_addr_t aic_start, l4_addr_t start, l4_addr_t end, void *cpm)    49 {    50   return x1600_aic_init(aic_start, start, end, cpm);    51 }    52     53 void *aic_get_channel(void *aic, int num, void *channel)    54 {    55   return x1600_aic_get_channel(aic, num, channel);    56 }    57     58 unsigned int aic_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,    59                           uint32_t count, uint32_t sample_rate,    60                           uint8_t sample_size)    61 {    62   return x1600_aic_transfer(channel, paddr, count, sample_rate, sample_size);    63 }    64     65     66     67 /* CPM adapter functions. */    68     69 void *cpm_init(l4_addr_t cpm_base)    70 {    71   return jz4780_cpm_init(cpm_base);    72 }    73     74 const char *cpm_clock_type(void *cpm, enum Clock_identifiers clock)    75 {    76   return jz4780_cpm_clock_type(cpm, clock);    77 }    78     79 int cpm_have_clock(void *cpm, enum Clock_identifiers clock)    80 {    81   return jz4780_cpm_have_clock(cpm, clock);    82 }    83     84 void cpm_start_clock(void *cpm, enum Clock_identifiers clock)    85 {    86   jz4780_cpm_start_clock(cpm, clock);    87 }    88     89 void cpm_stop_clock(void *cpm, enum Clock_identifiers clock)    90 {    91   jz4780_cpm_stop_clock(cpm, clock);    92 }    93     94 int cpm_get_parameters(void *cpm, enum Clock_identifiers clock,    95                        uint32_t parameters[])    96 {    97   return jz4780_cpm_get_parameters(cpm, clock, parameters);    98 }    99    100 int cpm_set_parameters(void *cpm, enum Clock_identifiers clock,   101                        int num_parameters, uint32_t parameters[])   102 {   103   return jz4780_cpm_set_parameters(cpm, clock, num_parameters, parameters);   104 }   105    106 uint8_t cpm_get_source(void *cpm, enum Clock_identifiers clock)   107 {   108   return jz4780_cpm_get_source(cpm, clock);   109 }   110    111 void cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source)   112 {   113   jz4780_cpm_set_source(cpm, clock, source);   114 }   115    116 enum Clock_identifiers cpm_get_source_clock(void *cpm, enum Clock_identifiers clock)   117 {   118   return jz4780_cpm_get_source_clock(cpm, clock);   119 }   120    121 void cpm_set_source_clock(void *cpm, enum Clock_identifiers clock, enum Clock_identifiers source)   122 {   123   jz4780_cpm_set_source_clock(cpm, clock, source);   124 }   125    126 uint64_t cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock)   127 {   128   return jz4780_cpm_get_source_frequency(cpm, clock);   129 }   130    131 uint64_t cpm_get_frequency(void *cpm, enum Clock_identifiers clock)   132 {   133   return jz4780_cpm_get_frequency(cpm, clock);   134 }   135    136 int cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint64_t frequency)   137 {   138   return jz4780_cpm_set_frequency(cpm, clock, frequency);   139 }   140    141    142    143 /* DMA adapter functions. */   144    145 void *dma_init(l4_addr_t start, l4_addr_t end, void *cpm)   146 {   147   return jz4780_dma_init(start, end, cpm);   148 }   149    150 void dma_disable(void *dma_chip)   151 {   152   jz4780_dma_disable(dma_chip);   153 }   154    155 void dma_enable(void *dma_chip)   156 {   157   jz4780_dma_enable(dma_chip);   158 }   159    160 void *dma_get_channel(void *dma, uint8_t channel, l4_cap_idx_t irq)   161 {   162   return jz4780_dma_get_channel(dma, channel, irq);   163 }   164    165 unsigned int dma_transfer(void *dma_channel,   166                           uint32_t source, uint32_t destination,   167                           unsigned int count,   168                           int source_increment, int destination_increment,   169                           uint8_t source_width, uint8_t destination_width,   170                           uint8_t transfer_unit_size,   171                           int type)   172 {   173   return jz4780_dma_transfer(dma_channel, source, destination, count,   174                              source_increment, destination_increment,   175                              source_width, destination_width,   176                              transfer_unit_size, type);   177 }   178    179 unsigned int dma_wait(void *dma_channel)   180 {   181   return jz4780_dma_wait(dma_channel);   182 }   183    184    185    186 /* GPIO adapter functions. */   187    188 void *gpio_init(l4_addr_t start, l4_addr_t end, unsigned pins,   189                 l4_uint32_t pull_ups, l4_uint32_t pull_downs)   190 {   191   return jz4780_gpio_init(start, end, pins, pull_ups, pull_downs);   192 }   193    194 void gpio_setup(void *gpio, unsigned pin, unsigned mode, int value)   195 {   196   jz4780_gpio_setup(gpio, pin, mode, value);   197 }   198    199 void gpio_config_pull(void *gpio, unsigned pin, unsigned mode)   200 {   201   jz4780_gpio_config_pull(gpio, pin, mode);   202 }   203    204 void gpio_config_pad(void *gpio, unsigned pin, unsigned func, unsigned value)   205 {   206   jz4780_gpio_config_pad(gpio, pin, func, value);   207 }   208    209 void gpio_config_get(void *gpio, unsigned pin, unsigned reg, unsigned *value)   210 {   211   jz4780_gpio_config_get(gpio, pin, reg, value);   212 }   213    214 void gpio_config_pad_get(void *gpio, unsigned pin, unsigned *func, unsigned *value)   215 {   216   jz4780_gpio_config_pad_get(gpio, pin, func, value);   217 }   218    219 void gpio_multi_setup(void *gpio, Pin_slice const *mask, unsigned mode, unsigned outvalues)   220 {   221   jz4780_gpio_multi_setup(gpio, mask, mode, outvalues);   222 }   223    224 void gpio_multi_config_pad(void *gpio, Pin_slice const *mask, unsigned func, unsigned value)   225 {   226   jz4780_gpio_multi_config_pad(gpio, mask, func, value);   227 }   228    229 void gpio_multi_set(void *gpio, Pin_slice const *mask, unsigned data)   230 {   231   jz4780_gpio_multi_set(gpio, mask, data);   232 }   233    234 unsigned gpio_multi_get(void *gpio, unsigned offset)   235 {   236   return jz4780_gpio_multi_get(gpio, offset);   237 }   238    239 int gpio_get(void *gpio, unsigned pin)   240 {   241   return jz4780_gpio_get(gpio, pin);   242 }   243    244 void gpio_set(void *gpio, unsigned pin, int value)   245 {   246   jz4780_gpio_set(gpio, pin, value);   247 }   248    249 void *gpio_get_irq(void *gpio, unsigned pin)   250 {   251   return jz4780_gpio_get_irq(gpio, pin);   252 }   253    254 bool gpio_irq_set_mode(void *gpio_irq, unsigned mode)   255 {   256   return jz4780_gpio_irq_set_mode(gpio_irq, mode);   257 }   258    259    260    261 /* I2C adapter functions. */   262    263 void *i2c_init(l4_addr_t start, l4_addr_t end, void *cpm,   264                uint32_t frequency)   265 {   266   return jz4780_i2c_init(start, end, cpm, frequency);   267 }   268    269 void *i2c_get_channel(void *i2c, uint8_t channel)   270 {   271   return jz4780_i2c_get_channel(i2c, channel);   272 }   273    274 uint32_t i2c_get_frequency(void *i2c_channel)   275 {   276   return jz4780_i2c_get_frequency(i2c_channel);   277 }   278    279 void i2c_set_target(void *i2c_channel, uint8_t addr)   280 {   281   return jz4780_i2c_set_target(i2c_channel, addr);   282 }   283    284 void i2c_start_read(void *i2c_channel, uint8_t buf[], unsigned int total,   285                     int stop)   286 {   287   jz4780_i2c_start_read(i2c_channel, buf, total, stop);   288 }   289    290 void i2c_read(void *i2c_channel)   291 {   292   jz4780_i2c_read(i2c_channel);   293 }   294    295 void i2c_start_write(void *i2c_channel, uint8_t buf[], unsigned int total,   296                      int stop)   297 {   298   jz4780_i2c_start_write(i2c_channel, buf, total, stop);   299 }   300    301 void i2c_write(void *i2c_channel)   302 {   303   jz4780_i2c_write(i2c_channel);   304 }   305    306 int i2c_read_done(void *i2c_channel)   307 {   308   return jz4780_i2c_read_done(i2c_channel);   309 }   310    311 int i2c_write_done(void *i2c_channel)   312 {   313   return jz4780_i2c_write_done(i2c_channel);   314 }   315    316 unsigned int i2c_have_read(void *i2c_channel)   317 {   318   return jz4780_i2c_have_read(i2c_channel);   319 }   320    321 unsigned int i2c_have_written(void *i2c_channel)   322 {   323   return jz4780_i2c_have_written(i2c_channel);   324 }   325    326 int i2c_failed(void *i2c_channel)   327 {   328   return jz4780_i2c_failed(i2c_channel);   329 }   330    331 void i2c_stop(void *i2c_channel)   332 {   333   jz4780_i2c_stop(i2c_channel);   334 }   335    336    337    338 /* RTC adapter functions. */   339    340 void *rtc_init(l4_addr_t start, void *cpm)   341 {   342   /* Ignore the CPM requirement for the JZ4780. */   343    344   (void) cpm;   345   return x1600_rtc_init(start, NULL);   346 }   347    348 void rtc_disable(void *rtc)   349 {   350   x1600_rtc_disable(rtc);   351 }   352    353 void rtc_enable(void *rtc)   354 {   355   x1600_rtc_enable(rtc);   356 }   357    358 void rtc_alarm_disable(void *rtc)   359 {   360   x1600_rtc_alarm_disable(rtc);   361 }   362    363 void rtc_alarm_enable(void *rtc)   364 {   365   x1600_rtc_alarm_enable(rtc);   366 }   367    368 uint32_t rtc_get_seconds(void *rtc)   369 {   370   return x1600_rtc_get_seconds(rtc);   371 }   372    373 void rtc_set_seconds(void *rtc, uint32_t seconds)   374 {   375   x1600_rtc_set_seconds(rtc, seconds);   376 }   377    378 uint32_t rtc_get_alarm_seconds(void *rtc)   379 {   380   return x1600_rtc_get_alarm_seconds(rtc);   381 }   382    383 void rtc_set_alarm_seconds(void *rtc, uint32_t seconds)   384 {   385   x1600_rtc_set_alarm_seconds(rtc, seconds);   386 }   387    388 void rtc_hibernate(void *rtc)   389 {   390   x1600_rtc_hibernate(rtc);   391 }   392    393 void rtc_power_down(void *rtc)   394 {   395   x1600_rtc_power_down(rtc);   396 }   397    398 void rtc_set_regulator(void *rtc, uint32_t base, uint32_t adjustment)   399 {   400   x1600_rtc_set_regulator(rtc, base, adjustment);   401 }   402    403    404    405 /* SPI adapter functions. */   406    407 void *spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, void *cpm)   408 {   409   return jz4780_spi_init(spi_start, start, end, cpm);   410 }   411    412 void *spi_get_channel(void *spi, uint8_t num, void *channel, uint64_t frequency,   413                       void *control_chip, int control_pin, int control_alt_func)   414 {   415   void *ch = jz4780_spi_get_channel(spi, num, channel, frequency);   416    417   return spi_hybrid_get_channel(ch, control_chip, control_pin, control_alt_func);   418 }   419    420 void *spi_get_channel_gpio(uint64_t frequency,   421                            void *clock_chip, int clock_pin,   422                            void *data_chip, int data_pin,   423                            void *enable_chip, int enable_pin,   424                            void *control_chip, int control_pin)   425 {   426   void *ch = spi_gpio_get_channel(frequency, clock_chip, clock_pin, data_chip,   427                                   data_pin, enable_chip, enable_pin, control_chip,   428                                   control_pin);   429    430   return spi_hybrid_get_channel(ch, control_chip, control_pin, -1);   431 }   432    433 void spi_acquire_control(void *channel, int level)   434 {   435   spi_hybrid_acquire_control(channel, level);   436 }   437    438 void spi_release_control(void *channel)   439 {   440   spi_hybrid_release_control(channel);   441 }   442    443 void spi_send(void *channel, uint32_t bytes, const uint8_t data[])   444 {   445   spi_hybrid_send(channel, bytes, data);   446 }   447    448 void spi_send_units(void *channel, uint32_t bytes, const uint8_t data[],   449                     uint8_t unit_size, uint8_t char_size, int big_endian)   450 {   451   spi_hybrid_send_units(channel, bytes, data, unit_size, char_size, big_endian);   452 }   453    454 uint32_t spi_transfer(void *channel, l4_addr_t vaddr,   455                       l4re_dma_space_dma_addr_t paddr, uint32_t count,   456                       uint8_t unit_size, uint8_t char_size,   457                       l4_addr_t desc_vaddr, l4re_dma_space_dma_addr_t desc_paddr)   458 {   459   return spi_hybrid_transfer_descriptor(channel, vaddr, paddr, count, unit_size,   460                                         char_size, desc_vaddr, desc_paddr);   461 }   462    463    464    465 /* Memory regions. */   466    467 const char *io_memory_regions[] = {   468   [AIC] = "jz4780-aic",   469   [CPM] = "jz4780-cpm",   470   [DMA] = "jz4780-dma",   471   [GPIO] = "jz4780-gpio",   472   [I2C] = "jz4780-i2c",   473   [RTC] = "jz4780-rtc",   474   [SSI] = "jz4780-ssi",   475 };   476    477    478    479 /* AIC definitions. */   480    481 void *aic_channels[] = {NULL, NULL};   482    483 const unsigned int num_aic_channels = 2;   484    485 l4_cap_idx_t aic_irqs[] = {L4_INVALID_CAP};   486    487    488    489 /* CPM definitions. */   490    491 struct clock_info clocks[] = {   492   {"ext",     Clock_external, "EXCLK"},   493   {"ext_512", Clock_external_div_512, "EXCLK/512"},   494   {"rtc_ext", Clock_rtc_external, "RTCLK"},   495   {"plla",    Clock_pll_A, "PLL A"},   496   {"plle",    Clock_pll_E, "PLL E"},   497   {"pllm",    Clock_pll_M, "PLL M"},   498   {"pllv",    Clock_pll_V, "PLL V"},   499   {"main",    Clock_main, "Main (SCLK_A)"},   500   {"cpu",     Clock_cpu, "CPU"},   501   {"l2c",     Clock_l2cache, "L2 cache"},   502   {"h2p",     Clock_hclock2_pclock, "AHB2/APB"},   503   {"ahb0",    Clock_hclock0, "AHB0"},   504   {"ahb2",    Clock_hclock2, "AHB2"},   505   {"apb",     Clock_pclock, "APB"},   506   {"dma",     Clock_dma, "DMA"},   507   {"hdmi",    Clock_lcd, "HDMI"},   508   {"lcd",     Clock_lcd, "LCD"},   509   {"lcd0",    Clock_lcd_pixel0, "LCD0 pixel"},   510   {"lcd1",    Clock_lcd_pixel1, "LCD1 pixel"},   511   {"msc",     Clock_msc, "MSC"},   512   {"msc0",    Clock_msc0, "MSC0"},   513   {"msc1",    Clock_msc1, "MSC1"},   514   {"msc2",    Clock_msc1, "MSC2"},   515   {"otg0",    Clock_otg0, "USB OTG0"},   516   {"otg1",    Clock_otg1, "USB OTG1"},   517   {"i2c0",    Clock_i2c0, "I2C0"},   518   {"i2c1",    Clock_i2c1, "I2C1"},   519   {"i2c2",    Clock_i2c2, "I2C2"},   520   {"i2c3",    Clock_i2c3, "I2C3"},   521   {"i2c4",    Clock_i2c4, "I2C4"},   522   {"i2s0",    Clock_i2s0, "I2S0"},   523   {"i2s1",    Clock_i2s1, "I2S1"},   524   {"pcm",     Clock_pcm, "PCM"},   525   {"rtc",     Clock_rtc, "RTC"},   526   {"ssi",     Clock_ssi, "SSI"},   527   {"ssi0",    Clock_ssi0, "SSI0"},   528   {"ssi1",    Clock_ssi1, "SSI1"},   529   {"uart0",   Clock_uart0, "UART0"},   530   {"uart1",   Clock_uart1, "UART1"},   531   {"uart2",   Clock_uart2, "UART2"},   532   {"uart3",   Clock_uart3, "UART3"},   533   {"uart4",   Clock_uart4, "UART4"},   534   {"usbphy",  Clock_usb_phy, "USB PHY"},   535   {NULL,      Clock_none, NULL},   536 };   537    538    539    540 /* DMA definitions. */   541    542 void *dma_channels[32] = {NULL};   543    544 const unsigned int num_dma_channels = 32;   545    546 struct dma_region dma_regions[8];   547    548 const unsigned int num_dma_regions = 8;   549    550 l4_cap_idx_t dma_irq = L4_INVALID_CAP;   551    552    553    554 /* GPIO definitions. */   555    556 struct gpio_port gpio_ports[] = {   557   {0x3fff00ff, 0x00000000},   558   {0xfff0f3fc, 0x000f0c03},   559   {0x0fffffff, 0x00000000},   560   {0xffff4fff, 0x0000b000},   561   {0xf0fff37c, 0x00000483},   562   {0x7fa7f00f, 0x00580ff0},   563 };   564    565 const unsigned int num_gpio_ports = 6;   566    567 const char gpio_port_labels[] = "ABCDEF";   568    569    570    571 /* I2C definitions. */   572    573 void *i2c_channels[] = {NULL, NULL, NULL, NULL, NULL};   574    575 const unsigned int num_i2c_channels = 5;   576    577 l4_cap_idx_t i2c_irqs[] = {L4_INVALID_CAP, L4_INVALID_CAP};   578    579    580    581 /* SPI definitions. */   582    583 void *spi_channels[] = {NULL, NULL};   584    585 const unsigned int num_spi_channels = 2;