From 3ba9fbefd56fd3da36a69a9a104589ef1df4fe10 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 11 Nov 2013 17:52:07 +0100 Subject: [PATCH] videomixer: generate EDID --- software/videomixer/Makefile | 2 +- software/videomixer/dvisamplerX.c | 9 +- software/videomixer/dvisamplerX.h | 2 +- software/videomixer/edid.c | 2 +- software/videomixer/edid.h | 2 +- software/videomixer/fb.c | 103 ---------------------- software/videomixer/fb.h | 16 ---- software/videomixer/main.c | 29 ++++--- software/videomixer/processor.c | 136 ++++++++++++++++++++++++++++++ software/videomixer/processor.h | 11 +++ 10 files changed, 171 insertions(+), 141 deletions(-) delete mode 100644 software/videomixer/fb.c delete mode 100644 software/videomixer/fb.h create mode 100644 software/videomixer/processor.c create mode 100644 software/videomixer/processor.h diff --git a/software/videomixer/Makefile b/software/videomixer/Makefile index 9ec2f718..9afe6341 100644 --- a/software/videomixer/Makefile +++ b/software/videomixer/Makefile @@ -1,7 +1,7 @@ MSCDIR=../.. include $(MSCDIR)/software/common.mak -OBJECTS=isr.o fb.o dvisampler0.o dvisampler1.o main.o +OBJECTS=isr.o processor.o dvisampler0.o dvisampler1.o edid.o main.o all: videomixer.bin videomixer.fbi diff --git a/software/videomixer/dvisamplerX.c b/software/videomixer/dvisamplerX.c index 19ebbbf6..636798fc 100644 --- a/software/videomixer/dvisamplerX.c +++ b/software/videomixer/dvisamplerX.c @@ -7,13 +7,12 @@ #include #include -#include "fb.h" #include "dvisamplerX.h" #define FRAMEBUFFER_COUNT 4 #define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1) -static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][1024*768] __attribute__((aligned(16))); +static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][1280*720] __attribute__((aligned(16))); static int dvisamplerX_fb_slot_indexes[2]; static int dvisamplerX_next_fb_index; @@ -40,7 +39,7 @@ void dvisamplerX_isr(void) fb_dmaX_base_write((unsigned int)dvisamplerX_framebuffers[fb_index]); } -void dvisamplerX_init_video(void) +void dvisamplerX_init_video(int hres, int vres) { unsigned int mask; @@ -52,7 +51,7 @@ void dvisamplerX_init_video(void) mask |= 1 << DVISAMPLERX_INTERRUPT; irq_setmask(mask); - dvisamplerX_dma_frame_size_write(fb_hres*fb_vres*4); + dvisamplerX_dma_frame_size_write(hres*vres*4); dvisamplerX_fb_slot_indexes[0] = 0; dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[0]); dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED); @@ -238,7 +237,6 @@ void dvisamplerX_service(void) dvisamplerX_connected = 0; dvisamplerX_locked = 0; dvisamplerX_clocking_pll_reset_write(1); - dvisamplerX_edid_hpd_en_write(0); } else { if(dvisamplerX_locked) { if(dvisamplerX_clocking_locked_read()) { @@ -263,7 +261,6 @@ void dvisamplerX_service(void) if(dvisamplerX_edid_hpd_notif_read()) { printf("dvisamplerX: connected\n"); dvisamplerX_connected = 1; - dvisamplerX_edid_hpd_en_write(1); dvisamplerX_clocking_pll_reset_write(0); } } diff --git a/software/videomixer/dvisamplerX.h b/software/videomixer/dvisamplerX.h index a5c9988f..300722a6 100644 --- a/software/videomixer/dvisamplerX.h +++ b/software/videomixer/dvisamplerX.h @@ -2,7 +2,7 @@ #define __DVISAMPLERX_H void dvisamplerX_isr(void); -void dvisamplerX_init_video(void); +void dvisamplerX_init_video(int hres, int vres); void dvisamplerX_print_status(void); int dvisamplerX_calibrate_delays(void); int dvisamplerX_adjust_phase(void); diff --git a/software/videomixer/edid.c b/software/videomixer/edid.c index 38cba6d6..4734189c 100644 --- a/software/videomixer/edid.c +++ b/software/videomixer/edid.c @@ -193,7 +193,7 @@ static void generate_unused(uint8_t *data_block) } void generate_edid(void *out, - const char mfg_name[3], uint8_t product_code[2], int year, + const char mfg_name[3], const char product_code[2], int year, const char *name, const struct video_timing *timing) { diff --git a/software/videomixer/edid.h b/software/videomixer/edid.h index 5c6b0a3f..34b1d624 100644 --- a/software/videomixer/edid.h +++ b/software/videomixer/edid.h @@ -20,7 +20,7 @@ struct video_timing { int validate_edid(const void *buf); void get_monitor_name(const void *buf, char *name); void generate_edid(void *out, - const char mfg_name[3], uint8_t product_code[2], int year, + const char mfg_name[3], const char product_code[2], int year, const char *name, const struct video_timing *timing); diff --git a/software/videomixer/fb.c b/software/videomixer/fb.c deleted file mode 100644 index 094cc1f8..00000000 --- a/software/videomixer/fb.c +++ /dev/null @@ -1,103 +0,0 @@ -#include - -#include -#include - -#include "fb.h" - -int fb_hres = 640; -int fb_vres = 480; - -static void fb_clkgen_write(int cmd, int data) -{ - int word; - - word = (data << 2) | cmd; - fb_driver_clocking_cmd_data_write(word); - fb_driver_clocking_send_cmd_data_write(1); - while(fb_driver_clocking_status_read() & CLKGEN_STATUS_BUSY); -} - -void fb_set_mode(int mode) -{ - int clock_m, clock_d; - - switch(mode) { - default: - case FB_MODE_640_480: // Pixel clock: 25MHz - fb_hres = 640; - fb_vres = 480; - clock_m = 2; - clock_d = 4; - fb_fi_hres_write(640); - fb_fi_hsync_start_write(656); - fb_fi_hsync_end_write(752); - fb_fi_hscan_write(800); - fb_fi_vres_write(480); - fb_fi_vsync_start_write(492); - fb_fi_vsync_end_write(494); - fb_fi_vscan_write(525); - break; - case FB_MODE_800_600: // Pixel clock: 50MHz - fb_hres = 800; - fb_vres = 600; - clock_m = 2; - clock_d = 2; - fb_fi_hres_write(800); - fb_fi_hsync_start_write(848); - fb_fi_hsync_end_write(976); - fb_fi_hscan_write(1040); - fb_fi_vres_write(600); - fb_fi_vsync_start_write(636); - fb_fi_vsync_end_write(642); - fb_fi_vscan_write(665); - break; - case FB_MODE_1024_768: // Pixel clock: 65MHz - fb_hres = 1024; - fb_vres = 768; - clock_m = 13; - clock_d = 10; - fb_fi_hres_write(1024); - fb_fi_hsync_start_write(1048); - fb_fi_hsync_end_write(1184); - fb_fi_hscan_write(1344); - fb_fi_vres_write(768); - fb_fi_vsync_start_write(772); - fb_fi_vsync_end_write(778); - fb_fi_vscan_write(807); - break; - case FB_MODE_1920_1080: // Pixel clock: 148MHz - fb_hres = 1920; - fb_vres = 1080; - clock_m = 74; - clock_d = 25; - fb_fi_hres_write(1920); - fb_fi_hsync_start_write(2008); - fb_fi_hsync_end_write(2052); - fb_fi_hscan_write(2200); - fb_fi_vres_write(1080); - fb_fi_vsync_start_write(1084); - fb_fi_vsync_end_write(1089); - fb_fi_vscan_write(1125); - break; - } - fb_dma0_length_write(fb_hres*fb_vres*4); - fb_dma1_length_write(fb_hres*fb_vres*4); - - fb_clkgen_write(0x1, clock_d-1); - fb_clkgen_write(0x3, clock_m-1); - fb_driver_clocking_send_go_write(1); - printf("waiting for PROGDONE..."); - while(!(fb_driver_clocking_status_read() & CLKGEN_STATUS_PROGDONE)); - printf("ok\n"); - printf("waiting for LOCKED..."); - while(!(fb_driver_clocking_status_read() & CLKGEN_STATUS_LOCKED)); - printf("ok\n"); - - printf("VGA: mode set to %dx%d\n", fb_hres, fb_vres); -} - -void fb_enable(int en) -{ - fb_enable_write(!!en); -} diff --git a/software/videomixer/fb.h b/software/videomixer/fb.h deleted file mode 100644 index 7b9cc926..00000000 --- a/software/videomixer/fb.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __FB_H -#define __FB_H - -enum { - FB_MODE_640_480, - FB_MODE_800_600, - FB_MODE_1024_768, - FB_MODE_1920_1080 -}; - -extern int fb_hres, fb_vres; - -void fb_set_mode(int mode); -void fb_enable(int en); - -#endif /* __FB_H */ diff --git a/software/videomixer/main.c b/software/videomixer/main.c index 1f79db4a..a4359edd 100644 --- a/software/videomixer/main.c +++ b/software/videomixer/main.c @@ -8,9 +8,7 @@ #include #include -#include "fb.h" -#include "dvisampler0.h" -#include "dvisampler1.h" +#include "processor.h" #ifdef POTS_BASE static int scale_pot(int raw, int range) @@ -92,10 +90,10 @@ static void fb_service(void) if(readchar_nonblock()) { c = readchar(); if(c == '1') { - fb_enable(1); + fb_enable_write(1); printf("Framebuffer is ON\n"); } else if(c == '0') { - fb_enable(0); + fb_enable_write(0); printf("Framebuffer is OFF\n"); } } @@ -119,23 +117,30 @@ static void membw_service(void) } } +static void list_video_modes(void) +{ + char mode_descriptors[PROCESSOR_MODE_COUNT*PROCESSOR_MODE_DESCLEN]; + int i; + + processor_list_modes(mode_descriptors); + for(i=0;i + +#include +#include + +#include "dvisampler0.h" +#include "dvisampler1.h" +#include "edid.h" +#include "processor.h" + +static const struct video_timing video_modes[PROCESSOR_MODE_COUNT] = { + { + .pixel_clock = 6500, + + .h_active = 1024, + .h_blanking = 320, + .h_sync_offset = 24, + .h_sync_width = 136, + + .v_active = 768, + .v_blanking = 38, + .v_sync_offset = 3, + .v_sync_width = 6 + }, { + .pixel_clock = 7425, + + .h_active = 1280, + .h_blanking = 370, + .h_sync_offset = 220, + .h_sync_width = 40, + + .v_active = 720, + .v_blanking = 30, + .v_sync_offset = 20, + .v_sync_width = 5 + } +}; + +void processor_list_modes(char *mode_descriptors) +{ + int i; + unsigned int refresh_span; + unsigned int refresh_rate; + + for(i=0;ipixel_clock, &clock_m, &clock_d); + + fb_fi_hres_write(mode->h_active); + fb_fi_hsync_start_write(mode->h_active + mode->h_sync_offset); + fb_fi_hsync_end_write(mode->h_active + mode->h_sync_offset + mode->h_sync_width); + fb_fi_hscan_write(mode->h_active + mode->h_blanking); + fb_fi_vres_write(mode->v_active); + fb_fi_vsync_start_write(mode->v_active + mode->v_sync_offset); + fb_fi_vsync_end_write(mode->v_active + mode->v_sync_offset + mode->v_sync_width); + fb_fi_vscan_write(mode->v_active + mode->v_blanking); + + fb_dma0_length_write(mode->h_active*mode->v_active*4); + fb_dma1_length_write(mode->h_active*mode->v_active*4); + + fb_clkgen_write(0x1, clock_d-1); + fb_clkgen_write(0x3, clock_m-1); + fb_driver_clocking_send_go_write(1); + printf("waiting for PROGDONE..."); + while(!(fb_driver_clocking_status_read() & CLKGEN_STATUS_PROGDONE)); + printf("ok\n"); + printf("waiting for LOCKED..."); + while(!(fb_driver_clocking_status_read() & CLKGEN_STATUS_LOCKED)); + printf("ok\n"); + + printf("Video mode set to %dx%d\n", mode->h_active, mode->v_active); +} + +static void edid_set_mode(const struct video_timing *mode) +{ + unsigned char edid[128]; + int i; + + generate_edid(&edid, "OHW", "MX", 2013, "Mixxeo ch.A", mode); + for(i=0;ih_active, m->v_active); + dvisampler1_init_video(m->h_active, m->v_active); + + fb_enable_write(1); + dvisampler0_edid_hpd_en_write(1); + dvisampler1_edid_hpd_en_write(1); +} + +void processor_service(void) +{ + dvisampler0_service(); + dvisampler1_service(); +} diff --git a/software/videomixer/processor.h b/software/videomixer/processor.h new file mode 100644 index 00000000..1a09b91d --- /dev/null +++ b/software/videomixer/processor.h @@ -0,0 +1,11 @@ +#ifndef __PROCESSOR_H +#define __PROCESSOR_H + +#define PROCESSOR_MODE_COUNT 2 +#define PROCESSOR_MODE_DESCLEN 32 + +void processor_list_modes(char *mode_descriptors); +void processor_start(int mode); +void processor_service(void); + +#endif /* __VIDEOMODE_H */ -- 2.30.2