From 6b308e5fc14b07e58291079c1f7184cbba81ca54 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Mon, 19 Jul 2021 19:50:41 +0900 Subject: [PATCH] i965: Send mode change signal? --- base/usr/include/kernel/video.h | 1 + kernel/video/lfbvideo.c | 2 +- modules/i965.c | 54 ++++++++++++++++++--------------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/base/usr/include/kernel/video.h b/base/usr/include/kernel/video.h index 9aeef539..7712672a 100644 --- a/base/usr/include/kernel/video.h +++ b/base/usr/include/kernel/video.h @@ -22,5 +22,6 @@ extern uint16_t lfb_resolution_y; extern uint16_t lfb_resolution_b; extern uint8_t * lfb_vid_memory; extern const char * lfb_driver_name; +extern void (*lfb_resolution_impl)(uint16_t,uint16_t); extern int framebuffer_initialize(void); #endif diff --git a/kernel/video/lfbvideo.c b/kernel/video/lfbvideo.c index 799c7713..f5539813 100644 --- a/kernel/video/lfbvideo.c +++ b/kernel/video/lfbvideo.c @@ -49,7 +49,7 @@ static int lfb_init(const char * c); static pid_t display_change_recipient = 0; /* Driver-specific modesetting function */ -static void (*lfb_resolution_impl)(uint16_t,uint16_t) = NULL; +void (*lfb_resolution_impl)(uint16_t,uint16_t) = NULL; /* Called by ioctl on /dev/fb0 */ void lfb_set_resolution(uint16_t x, uint16_t y) { diff --git a/modules/i965.c b/modules/i965.c index 4f2c6ac6..ce853de6 100644 --- a/modules/i965.c +++ b/modules/i965.c @@ -42,6 +42,34 @@ static void split(uint32_t val, uint32_t * a, uint32_t * b) { *b = (val >> 16) + 1; } +static void i965_modeset(uint16_t x, uint16_t y) { + /* Disable pipe A while we update source size */ + uint32_t pipe = i965_mmio_read(REG_PIPEACONF); + i965_mmio_write(REG_PIPEACONF, pipe & ~PIPEACONF_ENABLE); + while (i965_mmio_read(REG_PIPEACONF) & PIPEACONF_STATE); + + /* Set source size */ + i965_mmio_write(REG_PIPEASRC, ((x - 1) << 16) | (y - 1)); + + /* Re-enable pipe */ + pipe = i965_mmio_read(REG_PIPEACONF); + i965_mmio_write(REG_PIPEACONF, pipe | PIPEACONF_ENABLE); + while (!(i965_mmio_read(REG_PIPEACONF) & PIPEACONF_STATE)); + + /* Keep the plane enabled while we update stride value */ + i965_mmio_write(REG_DSPALINOFF, 0); /* offset to default of 0 */ + i965_mmio_write(REG_DSPASTRIDE, x * 4); /* stride to 4 x width */ + i965_mmio_write(REG_DSPASURF, 0); /* write to surface address triggers change; use default of 0 */ + + /* Update the values we expose to userspace. */ + lfb_resolution_x = x; + lfb_resolution_y = y; + lfb_resolution_b = 32; + lfb_resolution_s = i965_mmio_read(REG_DSPASTRIDE); + lfb_device->length = lfb_resolution_s * lfb_resolution_y; + +} + static void setup_framebuffer(uint32_t pcidev) { /* Map BAR space for the control registers */ uint32_t ctrl_space = pci_read_field(pcidev, PCI_BAR0, 4); @@ -52,30 +80,8 @@ static void setup_framebuffer(uint32_t pcidev) { ctrl_space &= 0xFFFFFF00; ctrl_regs = (uintptr_t)mmu_map_mmio_region(ctrl_space, ctrl_size); - /* Disable pipe A while we update source size */ - uint32_t pipe = i965_mmio_read(REG_PIPEACONF); - i965_mmio_write(REG_PIPEACONF, pipe & ~PIPEACONF_ENABLE); - while (i965_mmio_read(REG_PIPEACONF) & PIPEACONF_STATE); - - /* Set source size */ - i965_mmio_write(REG_PIPEASRC, ((1440 - 1) << 16) | (900 - 1)); - - /* Re-enable pipe */ - pipe = i965_mmio_read(REG_PIPEACONF); - i965_mmio_write(REG_PIPEACONF, pipe | PIPEACONF_ENABLE); - while (!(i965_mmio_read(REG_PIPEACONF) & PIPEACONF_STATE)); - - /* Keep the plane enabled while we update stride value */ - i965_mmio_write(REG_DSPALINOFF, 0); /* offset to default of 0 */ - i965_mmio_write(REG_DSPASTRIDE, 1440 * 4); /* stride to 4 x width */ - i965_mmio_write(REG_DSPASURF, 0); /* write to surface address triggers change; use default of 0 */ - - /* Update the values we expose to userspace. */ - lfb_resolution_x = 1440; - lfb_resolution_y = 900; - lfb_resolution_b = 32; - lfb_resolution_s = i965_mmio_read(REG_DSPASTRIDE); - lfb_device->length = lfb_resolution_s * lfb_resolution_y; + lfb_resolution_impl = i965_modeset; + lfb_set_resolution(1440,900); } static void find_intel(uint32_t device, uint16_t v, uint16_t d, void * extra) {