* Break DAC code into sperate source file
* Implement assigning DAC A/B to crt * Clean up mode change code * Still some pixel clock wierdness git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42205 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -13,6 +13,7 @@ Addon radeon_hd.accelerant :
|
|||||||
engine.cpp
|
engine.cpp
|
||||||
hooks.cpp
|
hooks.cpp
|
||||||
pll.cpp
|
pll.cpp
|
||||||
|
dac.cpp
|
||||||
mode.cpp
|
mode.cpp
|
||||||
bios.cpp
|
bios.cpp
|
||||||
create_display_modes.cpp
|
create_display_modes.cpp
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
#include "radeon_hd.h"
|
#include "radeon_hd.h"
|
||||||
#include "pll.h"
|
#include "pll.h"
|
||||||
|
#include "dac.h"
|
||||||
|
|
||||||
|
|
||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Alexander von Gluck, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "accelerant_protos.h"
|
||||||
|
#include "accelerant.h"
|
||||||
|
#include "utility.h"
|
||||||
|
#include "dac.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TRACE_DAC
|
||||||
|
#ifdef TRACE_DAC
|
||||||
|
extern "C" void _sPrintf(const char *format, ...);
|
||||||
|
# define TRACE(x...) _sPrintf("radeon_hd: " x)
|
||||||
|
#else
|
||||||
|
# define TRACE(x...) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DACGetElectrical(uint8 type, uint8 dac,
|
||||||
|
uint8 *bandgap, uint8 *whitefine)
|
||||||
|
{
|
||||||
|
radeon_shared_info &info = *gInfo->shared_info;
|
||||||
|
|
||||||
|
// These lookups are based on PCIID, maybe need
|
||||||
|
// to extract more from AtomBIOS?
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16 pciIdMin;
|
||||||
|
uint16 pciIdMax;
|
||||||
|
uint8 bandgap[2][4];
|
||||||
|
uint8 whitefine[2][4];
|
||||||
|
} list[] = {
|
||||||
|
{ 0x791E, 0x791F,
|
||||||
|
{ { 0x07, 0x07, 0x07, 0x07 },
|
||||||
|
{ 0x07, 0x07, 0x07, 0x07 } },
|
||||||
|
{ { 0x09, 0x09, 0x04, 0x09 },
|
||||||
|
{ 0x09, 0x09, 0x04, 0x09 } },
|
||||||
|
},
|
||||||
|
{ 0x793F, 0x7942,
|
||||||
|
{ { 0x09, 0x09, 0x09, 0x09 },
|
||||||
|
{ 0x09, 0x09, 0x09, 0x09 } },
|
||||||
|
{ { 0x0a, 0x0a, 0x08, 0x0a },
|
||||||
|
{ 0x0a, 0x0a, 0x08, 0x0a } },
|
||||||
|
},
|
||||||
|
{ 0x9500, 0x9519,
|
||||||
|
{ { 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00 } },
|
||||||
|
{ { 0x00, 0x00, 0x20, 0x00 },
|
||||||
|
{ 0x25, 0x25, 0x26, 0x26 } },
|
||||||
|
},
|
||||||
|
{ 0, 0,
|
||||||
|
{ { 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0 } },
|
||||||
|
{ { 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0 } }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
*bandgap = 0;
|
||||||
|
*whitefine = 0;
|
||||||
|
|
||||||
|
// TODO : ATOM BIOS Bandgap / Whitefine lookup
|
||||||
|
|
||||||
|
if (*bandgap == 0 || *whitefine == 0) {
|
||||||
|
int i = 0;
|
||||||
|
while (list[i].pciIdMin != 0) {
|
||||||
|
if (list[i].pciIdMin <= info.device_id
|
||||||
|
&& list[i].pciIdMax >= info.device_id) {
|
||||||
|
if (*bandgap == 0) *bandgap = list[i].bandgap[dac][type];
|
||||||
|
if (*whitefine == 0) *whitefine = list[i].whitefine[dac][type];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (list[i].pciIdMin != 0)
|
||||||
|
TRACE("%s: found new BandGap / WhiteFine in table for card!\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DACSet(uint8 dacIndex, uint32 crtid)
|
||||||
|
{
|
||||||
|
bool istv = false;
|
||||||
|
uint8 bandGap;
|
||||||
|
uint8 whiteFine;
|
||||||
|
|
||||||
|
// BIG TODO : NTSC, PAL, ETC. We assume VGA for now
|
||||||
|
uint8 standard = FORMAT_VGA; /* VGA */
|
||||||
|
|
||||||
|
DACGetElectrical(standard, dacIndex, &bandGap, &whiteFine);
|
||||||
|
|
||||||
|
uint32 mask = 0;
|
||||||
|
if (bandGap) mask |= 0xFF << 16;
|
||||||
|
if (whiteFine) mask |= 0xFF << 8;
|
||||||
|
|
||||||
|
uint32 dacOffset = (dacIndex == 1) ? REG_DACB_OFFSET : REG_DACA_OFFSET;
|
||||||
|
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_CONTROL1, standard, 0x000000FF);
|
||||||
|
/* white level fine adjust */
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_CONTROL1, (bandGap << 16)
|
||||||
|
| (whiteFine << 8), mask);
|
||||||
|
|
||||||
|
if (istv) {
|
||||||
|
/* tv enable */
|
||||||
|
if (dacIndex) /* TV mux only available on DACB */
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_CONTROL2,
|
||||||
|
0x00000100, 0x0000FF00);
|
||||||
|
|
||||||
|
/* select tv encoder */
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_SOURCE_SELECT,
|
||||||
|
0x00000002, 0x00000003);
|
||||||
|
} else {
|
||||||
|
if (dacIndex) /* TV mux only available on DACB */
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x0000FF00);
|
||||||
|
|
||||||
|
/* select a crtc */
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_SOURCE_SELECT,
|
||||||
|
crtid & 0x01, 0x00000003);
|
||||||
|
}
|
||||||
|
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_FORCE_OUTPUT_CNTL,
|
||||||
|
0x00000701, 0x00000701);
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_FORCE_DATA,
|
||||||
|
0, 0x0000FFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DACPower(uint8 dacIndex, int mode)
|
||||||
|
{
|
||||||
|
uint32 dacOffset = (dacIndex == 1) ? REG_DACB_OFFSET : REG_DACA_OFFSET;
|
||||||
|
uint32 powerdown;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
// TODO : RHD_POWER_OFF, etc
|
||||||
|
case RHD_POWER_ON:
|
||||||
|
// TODO : SensedType Detection?
|
||||||
|
powerdown = 0;
|
||||||
|
Write32(OUT, dacOffset + DACA_ENABLE, 1);
|
||||||
|
Write32(OUT, dacOffset + DACA_POWERDOWN, 0);
|
||||||
|
snooze(14);
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, powerdown, 0xFFFFFF00);
|
||||||
|
snooze(2);
|
||||||
|
Write32(OUT, dacOffset + DACA_FORCE_OUTPUT_CNTL, 0);
|
||||||
|
Write32Mask(OUT, dacOffset + DACA_SYNC_SELECT, 0, 0x00000101);
|
||||||
|
Write32(OUT, dacOffset + DACA_SYNC_TRISTATE_CONTROL, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Alexander von Gluck, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RADEON_HD_DAC_H
|
||||||
|
#define RADEON_HD_DAC_H
|
||||||
|
|
||||||
|
// DAC Offsets
|
||||||
|
#define REG_DACA_OFFSET 0
|
||||||
|
#define REG_DACB_OFFSET 0x200
|
||||||
|
#define RV620_REG_DACA_OFFSET 0
|
||||||
|
#define RV620_REG_DACB_OFFSET 0x100
|
||||||
|
|
||||||
|
// Signal types
|
||||||
|
#define FORMAT_PAL 0x0
|
||||||
|
#define FORMAT_NTSC 0x1
|
||||||
|
#define FORMAT_VGA 0x2
|
||||||
|
#define FORMAT_TvCV 0x3
|
||||||
|
|
||||||
|
void DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine);
|
||||||
|
void DACSet(uint8 dacIndex, uint32 crtid);
|
||||||
|
void DACPower(uint8 dacIndex, int mode);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -335,7 +335,7 @@ CardModeScale(display_mode *mode)
|
|||||||
status_t
|
status_t
|
||||||
radeon_set_display_mode(display_mode *mode)
|
radeon_set_display_mode(display_mode *mode)
|
||||||
{
|
{
|
||||||
int crtNumber = 0;
|
uint8 crtNumber = 0;
|
||||||
|
|
||||||
init_registers(crtNumber);
|
init_registers(crtNumber);
|
||||||
|
|
||||||
@@ -344,19 +344,20 @@ radeon_set_display_mode(display_mode *mode)
|
|||||||
CardBlankSet(false);
|
CardBlankSet(false);
|
||||||
CardModeSet(mode);
|
CardModeSet(mode);
|
||||||
CardModeScale(mode);
|
CardModeScale(mode);
|
||||||
|
|
||||||
#if 0
|
|
||||||
PLLSet(0, mode->timing.pixel_clock);
|
PLLSet(0, mode->timing.pixel_clock);
|
||||||
PLLPower(0, RHD_POWER_ON);
|
// Set pixel clock
|
||||||
DACPower(0, RHD_POWER_ON);
|
DACSet(0, 0);
|
||||||
#endif
|
// Set DAC A to crt 0
|
||||||
|
|
||||||
// ensure graphics are enabled and powered on
|
// ensure graphics are enabled and powered on (CRT Power)
|
||||||
|
// aka D1Power
|
||||||
Write32Mask(CRT, D1GRPH_ENABLE, 0x00000001, 0x00000001);
|
Write32Mask(CRT, D1GRPH_ENABLE, 0x00000001, 0x00000001);
|
||||||
snooze(2);
|
snooze(2);
|
||||||
Write32Mask(CRT, D1CRTC_CONTROL, 0, 0x01000000); /* enable read requests */
|
Write32Mask(CRT, D1CRTC_CONTROL, 0, 0x01000000); /* enable read requests */
|
||||||
Write32Mask(CRT, D1CRTC_CONTROL, 1, 1);
|
Write32Mask(CRT, D1CRTC_CONTROL, 1, 1);
|
||||||
|
|
||||||
|
DACPower(0, RHD_POWER_ON);
|
||||||
|
|
||||||
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
|
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
|
||||||
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
||||||
|
|
||||||
|
|||||||
@@ -576,26 +576,3 @@ DCCGCLKSet(uint8 pllIndex, int set)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DACPower(uint8 dacIndex, int mode)
|
|
||||||
{
|
|
||||||
uint32 dacOffset = (dacIndex == 1) ? REG_DACB_OFFSET : REG_DACA_OFFSET;
|
|
||||||
uint32 powerdown;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case RHD_POWER_ON:
|
|
||||||
// TODO : SensedType Detection?
|
|
||||||
powerdown = 0;
|
|
||||||
Write32(OUT, dacOffset + DACA_ENABLE, 1);
|
|
||||||
Write32(OUT, dacOffset + DACA_POWERDOWN, 0);
|
|
||||||
snooze(14);
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, powerdown, 0xFFFFFF00);
|
|
||||||
snooze(2);
|
|
||||||
Write32(OUT, dacOffset + DACA_FORCE_OUTPUT_CNTL, 0);
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_SYNC_SELECT, 0, 0x00000101);
|
|
||||||
Write32(OUT, dacOffset + DACA_SYNC_TRISTATE_CONTROL, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,6 @@
|
|||||||
#define RV620_DCCGCLK_GRAB 1
|
#define RV620_DCCGCLK_GRAB 1
|
||||||
#define RV620_DCCGCLK_RELEASE 2
|
#define RV620_DCCGCLK_RELEASE 2
|
||||||
|
|
||||||
// DAC Offsets
|
|
||||||
#define REG_DACA_OFFSET 0
|
|
||||||
#define REG_DACB_OFFSET 0x200
|
|
||||||
#define RV620_REG_DACA_OFFSET 0
|
|
||||||
#define RV620_REG_DACB_OFFSET 0x100
|
|
||||||
|
|
||||||
|
|
||||||
struct PLL_Control {
|
struct PLL_Control {
|
||||||
uint16 feedbackDivider; // 0xFFFF is the endmarker
|
uint16 feedbackDivider; // 0xFFFF is the endmarker
|
||||||
@@ -51,7 +45,6 @@ status_t PLLCalibrate(uint8 pllIndex);
|
|||||||
void PLLCRTCGrab(uint8 pllIndex, bool crt2);
|
void PLLCRTCGrab(uint8 pllIndex, bool crt2);
|
||||||
bool DCCGCLKAvailable(uint8 pllIndex);
|
bool DCCGCLKAvailable(uint8 pllIndex);
|
||||||
void DCCGCLKSet(uint8 pllIndex, int set);
|
void DCCGCLKSet(uint8 pllIndex, int set);
|
||||||
void DACPower(uint8 dacIndex, int mode);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* RADEON_HD_PLL_H */
|
#endif /* RADEON_HD_PLL_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user