Implemented correct Voodoo pixel clock calculation.
This commit is contained in:
parent
f75a24f539
commit
44f80b879e
1 changed files with 62 additions and 5 deletions
|
|
@ -144,8 +144,12 @@ typedef struct voodoo_t
|
||||||
int pci_enable;
|
int pci_enable;
|
||||||
|
|
||||||
uint8_t dac_data[8];
|
uint8_t dac_data[8];
|
||||||
int dac_reg;
|
int dac_reg, dac_reg_ff;
|
||||||
uint8_t dac_readdata;
|
uint8_t dac_readdata;
|
||||||
|
uint16_t dac_pll_regs[16];
|
||||||
|
|
||||||
|
float pixel_clock;
|
||||||
|
int line_time;
|
||||||
|
|
||||||
voodoo_params_t params;
|
voodoo_params_t params;
|
||||||
|
|
||||||
|
|
@ -3484,6 +3488,30 @@ static void voodoo_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
queue_command(voodoo, addr | FIFO_WRITEW_FB, val);
|
queue_command(voodoo, addr | FIFO_WRITEW_FB, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void voodoo_pixelclock_update(voodoo_t *voodoo)
|
||||||
|
{
|
||||||
|
int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2;
|
||||||
|
int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2;
|
||||||
|
int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07);
|
||||||
|
float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
|
||||||
|
double clock_const;
|
||||||
|
int line_length;
|
||||||
|
|
||||||
|
if ((voodoo->dac_data[6] & 0xf0) == 0x20 ||
|
||||||
|
(voodoo->dac_data[6] & 0xf0) == 0x60 ||
|
||||||
|
(voodoo->dac_data[6] & 0xf0) == 0x70)
|
||||||
|
t /= 2.0f;
|
||||||
|
|
||||||
|
line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff);
|
||||||
|
|
||||||
|
// pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length);
|
||||||
|
|
||||||
|
voodoo->pixel_clock = t;
|
||||||
|
|
||||||
|
clock_const = cpuclock / t;
|
||||||
|
voodoo->line_time = (int)((double)line_length * clock_const * (double)(1 << TIMER_SHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
||||||
{
|
{
|
||||||
voodoo_t *voodoo = (voodoo_t *)p;
|
voodoo_t *voodoo = (voodoo_t *)p;
|
||||||
|
|
@ -3570,6 +3598,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
||||||
|
|
||||||
case SST_hSync:
|
case SST_hSync:
|
||||||
voodoo->hSync = val;
|
voodoo->hSync = val;
|
||||||
|
voodoo_pixelclock_update(voodoo);
|
||||||
break;
|
break;
|
||||||
case SST_vSync:
|
case SST_vSync:
|
||||||
voodoo->vSync = val;
|
voodoo->vSync = val;
|
||||||
|
|
@ -3602,7 +3631,26 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
||||||
voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata];
|
voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
voodoo->dac_data[voodoo->dac_reg] = val & 0xff;
|
{
|
||||||
|
if (voodoo->dac_reg == 5)
|
||||||
|
{
|
||||||
|
if (!voodoo->dac_reg_ff)
|
||||||
|
voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val;
|
||||||
|
else
|
||||||
|
voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8);
|
||||||
|
// pclog("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]);
|
||||||
|
voodoo->dac_reg_ff = !voodoo->dac_reg_ff;
|
||||||
|
if (!voodoo->dac_reg_ff)
|
||||||
|
voodoo->dac_data[4]++;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voodoo->dac_data[voodoo->dac_reg] = val & 0xff;
|
||||||
|
voodoo->dac_reg_ff = 0;
|
||||||
|
}
|
||||||
|
voodoo_pixelclock_update(voodoo);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -3935,8 +3983,10 @@ void voodoo_callback(void *p)
|
||||||
|
|
||||||
if (voodoo->line >= voodoo->v_total)
|
if (voodoo->line >= voodoo->v_total)
|
||||||
voodoo->line = 0;
|
voodoo->line = 0;
|
||||||
|
if (voodoo->line_time)
|
||||||
voodoo->timer_count += TIMER_USEC * 32;
|
voodoo->timer_count += voodoo->line_time;
|
||||||
|
else
|
||||||
|
voodoo->timer_count += TIMER_USEC * 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void voodoo_add_status_info(char *s, int max_len, void *p)
|
static void voodoo_add_status_info(char *s, int max_len, void *p)
|
||||||
|
|
@ -3959,6 +4009,13 @@ static void voodoo_add_status_info(char *s, int max_len, void *p)
|
||||||
voodoo_time = 0;
|
voodoo_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void voodoo_speed_changed(void *p)
|
||||||
|
{
|
||||||
|
voodoo_t *voodoo = (voodoo_t *)p;
|
||||||
|
|
||||||
|
voodoo_pixelclock_update(voodoo);
|
||||||
|
}
|
||||||
|
|
||||||
void *voodoo_init()
|
void *voodoo_init()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
@ -4120,7 +4177,7 @@ device_t voodoo_device =
|
||||||
voodoo_init,
|
voodoo_init,
|
||||||
voodoo_close,
|
voodoo_close,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
voodoo_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
voodoo_add_status_info,
|
voodoo_add_status_info,
|
||||||
voodoo_config
|
voodoo_config
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue