videomixer: support resolution change at runtime
This commit is contained in:
parent
593867b92a
commit
69568adb8e
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __CI_H
|
||||||
|
#define __CI_H
|
||||||
|
|
||||||
|
void ci_service(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -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,10 +207,12 @@ int dvisamplerX_phase_startup(void)
|
||||||
while(1) {
|
while(1) {
|
||||||
attempts++;
|
attempts++;
|
||||||
dvisamplerX_calibrate_delays();
|
dvisamplerX_calibrate_delays();
|
||||||
printf("dvisamplerX: delays calibrated\n");
|
if(dvisamplerX_debug)
|
||||||
|
printf("dvisamplerX: delays calibrated\n");
|
||||||
ret = dvisamplerX_init_phase();
|
ret = dvisamplerX_init_phase();
|
||||||
if(ret) {
|
if(ret) {
|
||||||
printf("dvisamplerX: phase init OK\n");
|
if(dvisamplerX_debug)
|
||||||
|
printf("dvisamplerX: phase init OK\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
printf("dvisamplerX: phase init failed\n");
|
printf("dvisamplerX: phase init failed\n");
|
||||||
|
@ -225,15 +233,14 @@ 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()) {
|
||||||
printf("dvisamplerX: disconnected\n");
|
if(dvisamplerX_debug)
|
||||||
|
printf("dvisamplerX: disconnected\n");
|
||||||
dvisamplerX_connected = 0;
|
dvisamplerX_connected = 0;
|
||||||
dvisamplerX_locked = 0;
|
dvisamplerX_locked = 0;
|
||||||
dvisamplerX_clocking_pll_reset_write(1);
|
dvisamplerX_clocking_pll_reset_write(1);
|
||||||
|
@ -242,24 +249,29 @@ 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();
|
||||||
dvisamplerX_print_status();
|
if(dvisamplerX_debug)
|
||||||
|
dvisamplerX_print_status();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("dvisamplerX: lost PLL lock\n");
|
if(dvisamplerX_debug)
|
||||||
|
printf("dvisamplerX: lost PLL lock\n");
|
||||||
dvisamplerX_locked = 0;
|
dvisamplerX_locked = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(dvisamplerX_clocking_locked_read()) {
|
if(dvisamplerX_clocking_locked_read()) {
|
||||||
printf("dvisamplerX: PLL locked\n");
|
if(dvisamplerX_debug)
|
||||||
|
printf("dvisamplerX: PLL locked\n");
|
||||||
dvisamplerX_phase_startup();
|
dvisamplerX_phase_startup();
|
||||||
dvisamplerX_print_status();
|
if(dvisamplerX_debug)
|
||||||
|
dvisamplerX_print_status();
|
||||||
dvisamplerX_locked = 1;
|
dvisamplerX_locked = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(dvisamplerX_edid_hpd_notif_read()) {
|
if(dvisamplerX_edid_hpd_notif_read()) {
|
||||||
printf("dvisamplerX: connected\n");
|
if(dvisamplerX_debug)
|
||||||
|
printf("dvisamplerX: connected\n");
|
||||||
dvisamplerX_connected = 1;
|
dvisamplerX_connected = 1;
|
||||||
dvisamplerX_clocking_pll_reset_write(0);
|
dvisamplerX_clocking_pll_reset_write(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue