3.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4730.h Sun May 28 22:35:09 2023 +0200
3.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4730.h Mon May 29 21:18:33 2023 +0200
3.3 @@ -1,7 +1,7 @@
3.4 /*
3.5 * CPM (clock and power management) support for the JZ4730.
3.6 *
3.7 - * Copyright (C) 2017, 2018, 2020 Paul Boddie <paul@boddie.org.uk>
3.8 + * Copyright (C) 2017, 2018, 2020, 2023 Paul Boddie <paul@boddie.org.uk>
3.9 *
3.10 * This program is free software; you can redistribute it and/or
3.11 * modify it under the terms of the GNU General Public License as
3.12 @@ -71,6 +71,9 @@
3.13 void set_lcd_pixel_divider(uint16_t division);
3.14 void set_lcd_frequencies(uint32_t pclk, uint8_t ratio);
3.15
3.16 + void start_dma();
3.17 + void stop_dma();
3.18 +
3.19 void start_i2c();
3.20 void stop_i2c();
3.21
4.1 --- a/pkg/devices/lib/cpm/src/jz4730.cc Sun May 28 22:35:09 2023 +0200
4.2 +++ b/pkg/devices/lib/cpm/src/jz4730.cc Mon May 29 21:18:33 2023 +0200
4.3 @@ -3,7 +3,7 @@
4.4 * provided by the jz4730. The power management functionality could be exposed
4.5 * using a separate driver.
4.6 *
4.7 - * Copyright (C) 2017, 2018, 2020 Paul Boddie <paul@boddie.org.uk>
4.8 + * Copyright (C) 2017, 2018, 2020, 2023 Paul Boddie <paul@boddie.org.uk>
4.9 *
4.10 * This program is free software; you can redistribute it and/or
4.11 * modify it under the terms of the GNU General Public License as
4.12 @@ -288,6 +288,22 @@
4.13
4.14
4.15
4.16 +// DMA clock control.
4.17 +
4.18 +void
4.19 +Cpm_jz4730_chip::start_dma()
4.20 +{
4.21 + _regs[Clock_gate] = _regs[Clock_gate] & ~(1 << Clock_gate_dmac);
4.22 +}
4.23 +
4.24 +void
4.25 +Cpm_jz4730_chip::stop_dma()
4.26 +{
4.27 + _regs[Clock_gate] = _regs[Clock_gate] | (1 << Clock_gate_dmac);
4.28 +}
4.29 +
4.30 +
4.31 +
4.32 // I2C clock control.
4.33
4.34 void
5.1 --- a/pkg/landfall-examples/letux400_dma/letux400_dma.cc Sun May 28 22:35:09 2023 +0200
5.2 +++ b/pkg/landfall-examples/letux400_dma/letux400_dma.cc Mon May 29 21:18:33 2023 +0200
5.3 @@ -1,7 +1,7 @@
5.4 /*
5.5 * Test DMA transfers.
5.6 *
5.7 - * Copyright (C) 2018, 2020, 2021 Paul Boddie <paul@boddie.org.uk>
5.8 + * Copyright (C) 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
5.9 *
5.10 * This program is free software; you can redistribute it and/or
5.11 * modify it under the terms of the GNU General Public License as
5.12 @@ -25,14 +25,19 @@
5.13
5.14 #include <l4/re/c/util/cap_alloc.h>
5.15 #include <l4/re/c/dataspace.h>
5.16 +#include <l4/re/c/dma_space.h>
5.17 #include <l4/re/c/mem_alloc.h>
5.18 #include <l4/re/c/rm.h>
5.19 +#include <l4/re/protocols.h>
5.20
5.21 +#include <l4/sys/err.h>
5.22 #include <l4/sys/factory.h>
5.23 #include <l4/sys/icu.h>
5.24 #include <l4/sys/irq.h>
5.25 #include <l4/sys/rcv_endpoint.h>
5.26
5.27 +#include <l4/vbus/vbus.h>
5.28 +
5.29 #include <stdio.h>
5.30 #include <string.h>
5.31 #include <unistd.h>
5.32 @@ -53,14 +58,55 @@
5.33
5.34 int main(void)
5.35 {
5.36 + long err;
5.37 void *cpm;
5.38 - void *dma, *dma0;
5.39 + void *dmac, *dma0;
5.40 + l4_cap_idx_t dma, vbus;
5.41 +
5.42 + dma = l4re_util_cap_alloc();
5.43 + vbus = l4re_env_get_cap("vbus");
5.44 +
5.45 + if (l4_is_invalid_cap(dma))
5.46 + {
5.47 + printf("Could not allocate DMA capability.\n");
5.48 + return 1;
5.49 + }
5.50 +
5.51 + /* Create the DMA space. */
5.52 +
5.53 + err = l4_error(l4_factory_create(l4re_env()->mem_alloc, L4RE_PROTO_DMA_SPACE, dma));
5.54 +
5.55 + if (err)
5.56 + {
5.57 + printf("Could not create DMA space: %s\n", l4sys_errtostr(err));
5.58 + return 1;
5.59 + }
5.60 +
5.61 + l4vbus_device_handle_t device = L4VBUS_NULL;
5.62 + l4vbus_resource_t dma_resource;
5.63 +
5.64 + if (!find_resource(&device, &dma_resource, L4VBUS_RESOURCE_DMA_DOMAIN))
5.65 + {
5.66 + printf("Could not find DMA domain.\n");
5.67 + return 1;
5.68 + }
5.69 +
5.70 + err = l4vbus_assign_dma_domain(vbus, dma_resource.start,
5.71 + L4VBUS_DMAD_BIND | L4VBUS_DMAD_L4RE_DMA_SPACE,
5.72 + dma);
5.73 +
5.74 + if (err)
5.75 + {
5.76 + printf("Could not assign DMA space: %s\n", l4sys_errtostr(err));
5.77 + return 1;
5.78 + }
5.79
5.80 /* Allocate memory to test transfers. */
5.81
5.82 l4_cap_idx_t ds0_mem, ds1_mem;
5.83 l4_size_t ds0_size = L4_PAGESIZE, ds0_psize, ds1_size = L4_PAGESIZE, ds1_psize;
5.84 - l4_addr_t ds0_addr, ds0_paddr, ds1_addr, ds1_paddr;
5.85 + l4_addr_t ds0_addr, ds1_addr;
5.86 + l4re_dma_space_dma_addr_t ds0_paddr, ds1_paddr;
5.87
5.88 ds0_mem = l4re_util_cap_alloc();
5.89 ds1_mem = l4re_util_cap_alloc();
5.90 @@ -79,20 +125,24 @@
5.91 }
5.92
5.93 if (l4re_rm_attach((void **) &ds0_addr, ds0_size,
5.94 - L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
5.95 + L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_EAGER_MAP | L4RE_RM_F_RW,
5.96 ds0_mem, 0, L4_PAGESHIFT) ||
5.97 l4re_rm_attach((void **) &ds1_addr, ds1_size,
5.98 - L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
5.99 + L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_EAGER_MAP | L4RE_RM_F_RW,
5.100 ds1_mem, 0, L4_PAGESHIFT))
5.101 {
5.102 printf("Could not map memory.\n");
5.103 return 1;
5.104 }
5.105
5.106 - if (l4re_ds_phys(ds0_mem, 0, &ds0_paddr, &ds0_psize) ||
5.107 - l4re_ds_phys(ds1_mem, 0, &ds1_paddr, &ds1_psize))
5.108 + err = l4re_dma_space_map(dma, ds0_mem | L4_CAP_FPAGE_RW, 0, &ds0_psize, 0,
5.109 + L4RE_DMA_SPACE_BIDIRECTIONAL, &ds0_paddr) ||
5.110 + l4re_dma_space_map(dma, ds1_mem | L4_CAP_FPAGE_RW, 0, &ds1_psize, 0,
5.111 + L4RE_DMA_SPACE_BIDIRECTIONAL, &ds1_paddr);
5.112 +
5.113 + if (err)
5.114 {
5.115 - printf("Could not get physical addresses for memory.\n");
5.116 + printf("Could not get physical addresses for memory: %s\n", l4sys_errtostr(err));
5.117 return 1;
5.118 }
5.119
5.120 @@ -136,8 +186,6 @@
5.121
5.122 /* Create interrupt objects. */
5.123
5.124 - long err;
5.125 -
5.126 err = l4_error(l4_factory_create_irq(l4re_global_env->factory, irq0cap));
5.127
5.128 if (err)
5.129 @@ -192,18 +240,18 @@
5.130 /* Obtain CPM and DMA references. */
5.131
5.132 cpm = jz4730_cpm_init(cpm_base);
5.133 - dma = jz4730_dma_init(dma_base, dma_base_end, cpm);
5.134 - dma0 = jz4730_dma_get_channel(dma, 0, irq0cap);
5.135 + dmac = jz4730_dma_init(dma_base, dma_base_end, cpm);
5.136 + dma0 = jz4730_dma_get_channel(dmac, 0, irq0cap);
5.137
5.138 /* Enable DMA. */
5.139
5.140 printf("Enable DMA...\n");
5.141
5.142 - jz4730_dma_enable(dma);
5.143 + jz4730_dma_enable(dmac);
5.144
5.145 /* Transfer data between the allocated memory regions. */
5.146
5.147 - printf("Transfer from %lx to %lx...\n", ds0_paddr, ds1_paddr);
5.148 + printf("Transfer from %llx to %llx...\n", ds0_paddr, ds1_paddr);
5.149
5.150 unsigned int ntransferred = jz4730_dma_transfer(dma0, (uint32_t) ds0_paddr,
5.151 (uint32_t) ds1_paddr,