videomixer: support resolution change at runtime

This commit is contained in:
Sebastien Bourdeauducq 2013-11-11 23:20:21 +01:00
parent 593867b92a
commit 69568adb8e
7 changed files with 113 additions and 62 deletions

View File

@ -1,7 +1,7 @@
MSCDIR=../.. MSCDIR=../..
include $(MSCDIR)/software/common.mak include $(MSCDIR)/software/common.mak
OBJECTS=isr.o processor.o dvisampler0.o dvisampler1.o edid.o main.o OBJECTS=isr.o processor.o dvisampler0.o dvisampler1.o edid.o ci.o main.o
all: videomixer.bin videomixer.fbi all: videomixer.bin videomixer.fbi

76
software/videomixer/ci.c Normal file
View File

@ -0,0 +1,76 @@
#include <stdio.h>
#include <console.h>
#include <hw/csr.h>
#include "dvisampler0.h"
#include "dvisampler1.h"
#include "processor.h"
#include "ci.h"
static void print_mem_bandwidth(void)
{
unsigned long long int nr, nw;
unsigned long long int f;
unsigned int rdb, wrb;
lasmicon_bandwidth_update_write(1);
nr = lasmicon_bandwidth_nreads_read();
nw = lasmicon_bandwidth_nwrites_read();
f = identifier_frequency_read();
rdb = (nr*f >> (24 - 7))/1000000ULL;
wrb = (nw*f >> (24 - 7))/1000000ULL;
printf("read:%5dMbps write:%5dMbps all:%5dMbps\n", rdb, wrb, rdb + wrb);
}
static void list_video_modes(void)
{
char mode_descriptors[PROCESSOR_MODE_COUNT*PROCESSOR_MODE_DESCLEN];
int i;
processor_list_modes(mode_descriptors);
printf("==== Available video modes ====\n");
for(i=0;i<PROCESSOR_MODE_COUNT;i++)
printf(" %d: %s\n", i, &mode_descriptors[i*PROCESSOR_MODE_DESCLEN]);
printf("===============================\n");
}
void ci_service(void)
{
int c;
if(readchar_nonblock()) {
c = readchar();
if((c >= '0') && (c <= '9')) {
int m;
m = c - '0';
if(m < PROCESSOR_MODE_COUNT)
processor_start(m);
}
switch(c) {
case 'l':
list_video_modes();
break;
case 'D':
dvisampler0_debug = dvisampler1_debug = 1;
printf("DVI sampler debug is ON\n");
break;
case 'd':
dvisampler0_debug = dvisampler1_debug = 0;
printf("DVI sampler debug is OFF\n");
break;
case 'F':
fb_enable_write(1);
printf("framebuffer is ON\n");
break;
case 'f':
fb_enable_write(0);
printf("framebuffer is OFF\n");
break;
case 'm':
print_mem_bandwidth();
break;
}
}
}

6
software/videomixer/ci.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __CI_H
#define __CI_H
void ci_service(void);
#endif

View File

@ -9,6 +9,8 @@
#include "dvisamplerX.h" #include "dvisamplerX.h"
int dvisamplerX_debug;
#define FRAMEBUFFER_COUNT 4 #define FRAMEBUFFER_COUNT 4
#define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1) #define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1)
@ -39,11 +41,15 @@ void dvisamplerX_isr(void)
fb_dmaX_base_write((unsigned int)dvisamplerX_framebuffers[fb_index]); fb_dmaX_base_write((unsigned int)dvisamplerX_framebuffers[fb_index]);
} }
static int dvisamplerX_connected;
static int dvisamplerX_locked;
void dvisamplerX_init_video(int hres, int vres) void dvisamplerX_init_video(int hres, int vres)
{ {
unsigned int mask; unsigned int mask;
dvisamplerX_clocking_pll_reset_write(1); dvisamplerX_clocking_pll_reset_write(1);
dvisamplerX_connected = dvisamplerX_locked = 0;
dvisamplerX_dma_ev_pending_write(dvisamplerX_dma_ev_pending_read()); dvisamplerX_dma_ev_pending_write(dvisamplerX_dma_ev_pending_read());
dvisamplerX_dma_ev_enable_write(0x3); dvisamplerX_dma_ev_enable_write(0x3);
@ -96,7 +102,7 @@ static int wait_idelays(void)
|| dvisamplerX_data1_cap_dly_busy_read() || dvisamplerX_data1_cap_dly_busy_read()
|| dvisamplerX_data2_cap_dly_busy_read()) { || dvisamplerX_data2_cap_dly_busy_read()) {
if(elapsed(&ev, identifier_frequency_read() >> 6) == 0) { if(elapsed(&ev, identifier_frequency_read() >> 6) == 0) {
printf("IDELAY busy timeout\n"); printf("dvisamplerX: IDELAY busy timeout\n");
return 0; return 0;
} }
} }
@ -201,9 +207,11 @@ int dvisamplerX_phase_startup(void)
while(1) { while(1) {
attempts++; attempts++;
dvisamplerX_calibrate_delays(); dvisamplerX_calibrate_delays();
if(dvisamplerX_debug)
printf("dvisamplerX: delays calibrated\n"); printf("dvisamplerX: delays calibrated\n");
ret = dvisamplerX_init_phase(); ret = dvisamplerX_init_phase();
if(ret) { if(ret) {
if(dvisamplerX_debug)
printf("dvisamplerX: phase init OK\n"); printf("dvisamplerX: phase init OK\n");
return 1; return 1;
} else { } else {
@ -225,14 +233,13 @@ static void dvisamplerX_check_overflow(void)
} }
} }
static int dvisamplerX_connected;
static int dvisamplerX_locked;
static int dvisamplerX_last_event; static int dvisamplerX_last_event;
void dvisamplerX_service(void) void dvisamplerX_service(void)
{ {
if(dvisamplerX_connected) { if(dvisamplerX_connected) {
if(!dvisamplerX_edid_hpd_notif_read()) { if(!dvisamplerX_edid_hpd_notif_read()) {
if(dvisamplerX_debug)
printf("dvisamplerX: disconnected\n"); printf("dvisamplerX: disconnected\n");
dvisamplerX_connected = 0; dvisamplerX_connected = 0;
dvisamplerX_locked = 0; dvisamplerX_locked = 0;
@ -242,16 +249,20 @@ void dvisamplerX_service(void)
if(dvisamplerX_clocking_locked_read()) { if(dvisamplerX_clocking_locked_read()) {
if(elapsed(&dvisamplerX_last_event, identifier_frequency_read()/2)) { if(elapsed(&dvisamplerX_last_event, identifier_frequency_read()/2)) {
dvisamplerX_adjust_phase(); dvisamplerX_adjust_phase();
if(dvisamplerX_debug)
dvisamplerX_print_status(); dvisamplerX_print_status();
} }
} else { } else {
if(dvisamplerX_debug)
printf("dvisamplerX: lost PLL lock\n"); printf("dvisamplerX: lost PLL lock\n");
dvisamplerX_locked = 0; dvisamplerX_locked = 0;
} }
} else { } else {
if(dvisamplerX_clocking_locked_read()) { if(dvisamplerX_clocking_locked_read()) {
if(dvisamplerX_debug)
printf("dvisamplerX: PLL locked\n"); printf("dvisamplerX: PLL locked\n");
dvisamplerX_phase_startup(); dvisamplerX_phase_startup();
if(dvisamplerX_debug)
dvisamplerX_print_status(); dvisamplerX_print_status();
dvisamplerX_locked = 1; dvisamplerX_locked = 1;
} }
@ -259,6 +270,7 @@ void dvisamplerX_service(void)
} }
} else { } else {
if(dvisamplerX_edid_hpd_notif_read()) { if(dvisamplerX_edid_hpd_notif_read()) {
if(dvisamplerX_debug)
printf("dvisamplerX: connected\n"); printf("dvisamplerX: connected\n");
dvisamplerX_connected = 1; dvisamplerX_connected = 1;
dvisamplerX_clocking_pll_reset_write(0); dvisamplerX_clocking_pll_reset_write(0);

View File

@ -1,6 +1,8 @@
#ifndef __DVISAMPLERX_H #ifndef __DVISAMPLERX_H
#define __DVISAMPLERX_H #define __DVISAMPLERX_H
extern int dvisamplerX_debug;
void dvisamplerX_isr(void); void dvisamplerX_isr(void);
void dvisamplerX_init_video(int hres, int vres); void dvisamplerX_init_video(int hres, int vres);
void dvisamplerX_print_status(void); void dvisamplerX_print_status(void);

View File

@ -8,6 +8,7 @@
#include <hw/flags.h> #include <hw/flags.h>
#include <console.h> #include <console.h>
#include "ci.h"
#include "processor.h" #include "processor.h"
#ifdef POTS_BASE #ifdef POTS_BASE
@ -83,50 +84,6 @@ static void ui_service(void)
#endif #endif
static void fb_service(void)
{
int c;
if(readchar_nonblock()) {
c = readchar();
if(c == '1') {
fb_enable_write(1);
printf("Framebuffer is ON\n");
} else if(c == '0') {
fb_enable_write(0);
printf("Framebuffer is OFF\n");
}
}
}
static void membw_service(void)
{
static int last_event;
unsigned long long int nr, nw;
unsigned long long int f;
unsigned int rdb, wrb;
if(elapsed(&last_event, identifier_frequency_read())) {
lasmicon_bandwidth_update_write(1);
nr = lasmicon_bandwidth_nreads_read();
nw = lasmicon_bandwidth_nwrites_read();
f = identifier_frequency_read();
rdb = (nr*f >> (24 - 7))/1000000ULL;
wrb = (nw*f >> (24 - 7))/1000000ULL;
printf("read:%5dMbps write:%5dMbps all:%5dMbps\n", rdb, wrb, rdb + wrb);
}
}
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<PROCESSOR_MODE_COUNT;i++)
printf("%d: %s\n", i, &mode_descriptors[i*PROCESSOR_MODE_DESCLEN]);
}
int main(void) int main(void)
{ {
irq_setmask(0); irq_setmask(0);
@ -136,14 +93,12 @@ int main(void)
printf("Mixxeo software rev. %08x built "__DATE__" "__TIME__"\n\n", GIT_ID); printf("Mixxeo software rev. %08x built "__DATE__" "__TIME__"\n\n", GIT_ID);
time_init(); time_init();
list_video_modes(); processor_start(2);
processor_start(0);
while(1) { while(1) {
processor_service(); processor_service();
ui_service(); ui_service();
fb_service(); ci_service();
membw_service();
} }
return 0; return 0;

View File

@ -124,6 +124,8 @@ static void fb_set_mode(const struct video_timing *mode)
{ {
unsigned int clock_m, clock_d; unsigned int clock_m, clock_d;
printf("setting video mode %dx%d\n", mode->h_active, mode->v_active);
fb_get_clock_md(mode->pixel_clock, &clock_m, &clock_d); fb_get_clock_md(mode->pixel_clock, &clock_m, &clock_d);
fb_fi_hres_write(mode->h_active); fb_fi_hres_write(mode->h_active);
@ -147,8 +149,6 @@ static void fb_set_mode(const struct video_timing *mode)
printf("waiting for LOCKED..."); printf("waiting for LOCKED...");
while(!(fb_driver_clocking_status_read() & CLKGEN_STATUS_LOCKED)); while(!(fb_driver_clocking_status_read() & CLKGEN_STATUS_LOCKED));
printf("ok\n"); 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) static void edid_set_mode(const struct video_timing *mode)