1.1 --- a/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Sat Jun 10 22:45:54 2023 +0200
1.2 +++ b/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Sat Jun 10 23:30:38 2023 +0200
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * Access the HDMI I2C peripheral on the MIPS Creator CI20 board.
1.6 *
1.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License as
1.12 @@ -30,12 +30,15 @@
1.13 #include <l4/devices/memory.h>
1.14
1.15 #include <l4/re/c/dataspace.h>
1.16 +#include <l4/re/c/dma_space.h>
1.17 #include <l4/re/c/mem_alloc.h>
1.18 #include <l4/re/c/rm.h>
1.19 #include <l4/re/c/util/cap_alloc.h>
1.20 #include <l4/re/env.h>
1.21 +#include <l4/re/protocols.h>
1.22
1.23 #include <l4/sys/cache.h>
1.24 +#include <l4/sys/err.h>
1.25 #include <l4/sys/factory.h>
1.26 #include <l4/sys/icu.h>
1.27 #include <l4/sys/ipc.h>
1.28 @@ -146,9 +149,10 @@
1.29
1.30 /* Allocated memory. */
1.31
1.32 - l4_cap_idx_t desc_mem, fb_mem;
1.33 + l4_cap_idx_t desc_mem, fb_mem, dma, vbus;
1.34 l4_size_t desc_size, desc_psize, fb_size, fb_psize;
1.35 - l4_addr_t desc_addr, desc_paddr, fb_addr, fb_paddr;
1.36 + l4_addr_t desc_addr, fb_addr;
1.37 + l4re_dma_space_dma_addr_t desc_paddr, fb_paddr;
1.38 unsigned char *picture;
1.39 unsigned char *fb_picture, *fb_picture_row;
1.40 unsigned int x, y;
1.41 @@ -157,17 +161,19 @@
1.42
1.43 l4_uint32_t hdmi_irq_start = 0, hdmi_irq_end = 0;
1.44 l4_uint32_t lcd_irq_start = 0, lcd_irq_end = 0;
1.45 - l4_cap_idx_t icucap, hdmi_irq, lcd_irq;
1.46 + l4_cap_idx_t icu, hdmi_irq, lcd_irq;
1.47
1.48 /* Capability allocation. */
1.49
1.50 desc_mem = l4re_util_cap_alloc();
1.51 fb_mem = l4re_util_cap_alloc();
1.52 + dma = l4re_util_cap_alloc();
1.53 hdmi_irq = l4re_util_cap_alloc();
1.54 lcd_irq = l4re_util_cap_alloc();
1.55 - icucap = l4re_env_get_cap("icu");
1.56 + icu = l4re_env_get_cap("icu");
1.57 + vbus = l4re_env_get_cap("vbus");
1.58
1.59 - if (l4_is_invalid_cap(icucap))
1.60 + if (l4_is_invalid_cap(icu))
1.61 {
1.62 printf("No 'icu' capability available in the virtual bus.\n");
1.63 return 1;
1.64 @@ -208,10 +214,10 @@
1.65 /* Bind interrupt objects to IRQ numbers. Here, the first HDMI interrupt is
1.66 bound, this being the general HDMI interrupt. */
1.67
1.68 - err = l4_error(l4_icu_bind(icucap,
1.69 + err = l4_error(l4_icu_bind(icu,
1.70 item_in_range(hdmi_irq_start, hdmi_irq_end, 0),
1.71 hdmi_irq)) ||
1.72 - l4_error(l4_icu_bind(icucap,
1.73 + l4_error(l4_icu_bind(icu,
1.74 item_in_range(lcd_irq_start, lcd_irq_end, 0),
1.75 lcd_irq));
1.76
1.77 @@ -353,38 +359,75 @@
1.78
1.79 jz4780_hdmi_enable(hdmi, jz4780_cpm_get_frequency(cpm, Clock_frequency_lcd_pixel));
1.80
1.81 + /* Create the DMA space. */
1.82 +
1.83 + err = l4_error(l4_factory_create(l4re_env()->mem_alloc, L4RE_PROTO_DMA_SPACE, dma));
1.84 +
1.85 + if (err)
1.86 + {
1.87 + printf("Could not create DMA space: %s\n", l4sys_errtostr(err));
1.88 + return 1;
1.89 + }
1.90 +
1.91 + l4vbus_device_handle_t device = L4VBUS_NULL;
1.92 + l4vbus_resource_t dma_resource;
1.93 +
1.94 + if (!find_resource(&device, &dma_resource, L4VBUS_RESOURCE_DMA_DOMAIN))
1.95 + {
1.96 + printf("Could not find DMA domain.\n");
1.97 + return 1;
1.98 + }
1.99 +
1.100 + err = l4vbus_assign_dma_domain(vbus, dma_resource.start,
1.101 + L4VBUS_DMAD_BIND | L4VBUS_DMAD_L4RE_DMA_SPACE,
1.102 + dma);
1.103 +
1.104 + if (err)
1.105 + {
1.106 + printf("Could not assign DMA space: %s\n", l4sys_errtostr(err));
1.107 + return 1;
1.108 + }
1.109 +
1.110 /* Allocate descriptors and framebuffer at 2**8 == 256 byte == 64 word alignment. */
1.111
1.112 desc_size = jz4740_lcd_get_descriptors_size(lcd);
1.113 fb_size = jz4740_lcd_get_screen_size(lcd);
1.114
1.115 - if (l4re_ma_alloc_align(desc_size, desc_mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED, 8) ||
1.116 - l4re_ma_alloc_align(fb_size, fb_mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED, 8))
1.117 + err = l4re_ma_alloc_align(desc_size, desc_mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED, 8) ||
1.118 + l4re_ma_alloc_align(fb_size, fb_mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED, 8);
1.119 +
1.120 + if (err)
1.121 {
1.122 - printf("Could not allocate memory.\n");
1.123 + printf("Could not allocate memory: %s\n", l4sys_errtostr(err));
1.124 return 1;
1.125 }
1.126
1.127 - if (l4re_rm_attach((void **) &desc_addr, desc_size,
1.128 - L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
1.129 - desc_mem, 0, L4_PAGESHIFT) ||
1.130 - l4re_rm_attach((void **) &fb_addr, fb_size,
1.131 - L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
1.132 - fb_mem, 0, L4_PAGESHIFT))
1.133 + err = l4re_rm_attach((void **) &desc_addr, desc_size,
1.134 + L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_EAGER_MAP | L4RE_RM_F_RW,
1.135 + desc_mem, 0, L4_PAGESHIFT) ||
1.136 + l4re_rm_attach((void **) &fb_addr, fb_size,
1.137 + L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_EAGER_MAP | L4RE_RM_F_RW,
1.138 + fb_mem, 0, L4_PAGESHIFT);
1.139 +
1.140 + if (err)
1.141 {
1.142 - printf("Could not map memory.\n");
1.143 + printf("Could not map memory: %s\n", l4sys_errtostr(err));
1.144 return 1;
1.145 }
1.146
1.147 - if (l4re_ds_phys(desc_mem, 0, &desc_paddr, &desc_psize) ||
1.148 - l4re_ds_phys(fb_mem, 0, &fb_paddr, &fb_psize))
1.149 + err = l4re_dma_space_map(dma, desc_mem | L4_CAP_FPAGE_RW, 0, &desc_psize, 0,
1.150 + L4RE_DMA_SPACE_TO_DEVICE, &desc_paddr) ||
1.151 + l4re_dma_space_map(dma, fb_mem | L4_CAP_FPAGE_RW, 0, &fb_psize, 0,
1.152 + L4RE_DMA_SPACE_TO_DEVICE, &fb_paddr);
1.153 +
1.154 + if (err)
1.155 {
1.156 - printf("Could not get physical addresses for memory.\n");
1.157 + printf("Could not get physical addresses for memory: %s\n", l4sys_errtostr(err));
1.158 return 1;
1.159 }
1.160
1.161 - printf("Descriptors at %lx/%lx, size %d/%d.\n", desc_addr, desc_paddr, desc_size, desc_psize);
1.162 - printf("Framebuffer at %lx/%lx, size %d/%d.\n", fb_addr, fb_paddr, fb_size, fb_psize);
1.163 + printf("Descriptors at %lx/%llx, size %d/%d.\n", desc_addr, desc_paddr, desc_size, desc_psize);
1.164 + printf("Framebuffer at %lx/%llx, size %d/%d.\n", fb_addr, fb_paddr, fb_size, fb_psize);
1.165
1.166 //memset((void *) fb_addr, 0x7f, fb_size);
1.167