* RIP Radeon register banging
Remove old non-atombios code * add encoder.c and encoder.h to handle encoder management * fix pll code to use encoder object id vs crtcid git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42797 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f35af704c8
commit
7c91a33c84
@ -13,13 +13,11 @@ Addon radeon_hd.accelerant :
|
|||||||
atom.cpp
|
atom.cpp
|
||||||
gpu.cpp
|
gpu.cpp
|
||||||
accelerant.cpp
|
accelerant.cpp
|
||||||
|
encoder.cpp
|
||||||
engine.cpp
|
engine.cpp
|
||||||
hooks.cpp
|
hooks.cpp
|
||||||
pll.cpp
|
pll.cpp
|
||||||
dac.cpp
|
|
||||||
display.cpp
|
display.cpp
|
||||||
tmds.cpp
|
|
||||||
lvds.cpp
|
|
||||||
mode.cpp
|
mode.cpp
|
||||||
bios.cpp
|
bios.cpp
|
||||||
create_display_modes.cpp
|
create_display_modes.cpp
|
||||||
|
@ -11,12 +11,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "encoder.h"
|
||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
#include "radeon_hd.h"
|
#include "radeon_hd.h"
|
||||||
#include "pll.h"
|
#include "pll.h"
|
||||||
#include "dac.h"
|
|
||||||
#include "tmds.h"
|
|
||||||
#include "lvds.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
|
@ -1,390 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Alexander von Gluck, kallisti5@unixzen.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
dac_sense(uint32 connector_id)
|
|
||||||
{
|
|
||||||
uint16 flags = gConnector[connector_id]->connector_flags;
|
|
||||||
|
|
||||||
if (flags & (ATOM_DEVICE_CRT_SUPPORT
|
|
||||||
| ATOM_DEVICE_CV_SUPPORT
|
|
||||||
| ATOM_DEVICE_TV_SUPPORT)) {
|
|
||||||
|
|
||||||
DAC_LOAD_DETECTION_PS_ALLOCATION args;
|
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
|
|
||||||
uint8 frev, crev;
|
|
||||||
memset(&args, 0, sizeof(args));
|
|
||||||
|
|
||||||
if (!atom_parse_cmd_header(gAtomContext, index, &frev, &crev))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
args.sDacload.ucMisc = 0;
|
|
||||||
|
|
||||||
if ((flags & ENCODER_OBJECT_ID_INTERNAL_DAC1)
|
|
||||||
|| (flags & ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))
|
|
||||||
args.sDacload.ucDacType = ATOM_DAC_A;
|
|
||||||
else
|
|
||||||
args.sDacload.ucDacType = ATOM_DAC_B;
|
|
||||||
|
|
||||||
if (flags & ATOM_DEVICE_CRT1_SUPPORT) {
|
|
||||||
args.sDacload.usDeviceID
|
|
||||||
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT1_SUPPORT);
|
|
||||||
} else if (flags & ATOM_DEVICE_CRT2_SUPPORT) {
|
|
||||||
args.sDacload.usDeviceID
|
|
||||||
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT2_SUPPORT);
|
|
||||||
} else if (flags & ATOM_DEVICE_CV_SUPPORT) {
|
|
||||||
args.sDacload.usDeviceID
|
|
||||||
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CV_SUPPORT);
|
|
||||||
if (crev >= 3)
|
|
||||||
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
|
|
||||||
} else if (flags & ATOM_DEVICE_TV1_SUPPORT) {
|
|
||||||
args.sDacload.usDeviceID
|
|
||||||
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_TV1_SUPPORT);
|
|
||||||
if (crev >= 3)
|
|
||||||
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
|
|
||||||
}
|
|
||||||
|
|
||||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
|
||||||
|
|
||||||
uint32 bios_0_scratch;
|
|
||||||
|
|
||||||
bios_0_scratch = Read32(OUT, R600_BIOS_0_SCRATCH);
|
|
||||||
|
|
||||||
if (flags & ATOM_DEVICE_CRT1_SUPPORT) {
|
|
||||||
if (bios_0_scratch & ATOM_S0_CRT1_MASK)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (flags & ATOM_DEVICE_CRT2_SUPPORT) {
|
|
||||||
if (bios_0_scratch & ATOM_S0_CRT2_MASK)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (flags & ATOM_DEVICE_CV_SUPPORT) {
|
|
||||||
if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (flags & ATOM_DEVICE_TV1_SUPPORT) {
|
|
||||||
if (bios_0_scratch
|
|
||||||
& (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
|
|
||||||
return true; /* CTV */
|
|
||||||
else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
|
|
||||||
return true; /* STV */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* For Cards >= r620 */
|
|
||||||
void
|
|
||||||
DACSetModern(uint8 dacIndex, uint32 crtid)
|
|
||||||
{
|
|
||||||
bool istv = false;
|
|
||||||
|
|
||||||
// BIG TODO : NTSC, PAL, ETC. We assume VGA for now
|
|
||||||
uint8 standard = FORMAT_VGA; /* VGA */
|
|
||||||
uint32 mode = 2;
|
|
||||||
uint32 source = istv ? 0x2 : crtid;
|
|
||||||
|
|
||||||
uint8 bandGap;
|
|
||||||
uint8 whiteFine;
|
|
||||||
DACGetElectrical(standard, dacIndex, &bandGap, &whiteFine);
|
|
||||||
|
|
||||||
uint32 mask = 0;
|
|
||||||
if (bandGap)
|
|
||||||
mask |= 0xFF << 16;
|
|
||||||
if (whiteFine)
|
|
||||||
mask |= 0xFF << 8;
|
|
||||||
|
|
||||||
uint32 dacOffset = dacIndex == 1 ? RV620_REG_DACA_OFFSET
|
|
||||||
: RV620_REG_DACB_OFFSET;
|
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_MACRO_CNTL, mode, 0xFF);
|
|
||||||
// no fine control yet
|
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_SOURCE_SELECT, source, 0x00000003);
|
|
||||||
|
|
||||||
// enable tv if has TV mux(DACB) and istv
|
|
||||||
if (dacIndex)
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_CONTROL2, istv << 8, 0x0100);
|
|
||||||
|
|
||||||
// use fine control from white_fine control register
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_AUTO_CALIB_CONTROL, 0x0, 0x4);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_BGADJ_SRC, 0x0, 0x30);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_MACRO_CNTL,
|
|
||||||
(bandGap << 16) | (whiteFine << 8), mask);
|
|
||||||
|
|
||||||
// reset the FMT register
|
|
||||||
// TODO : ah-la external DxFMTSet
|
|
||||||
uint32 fmtOffset = crtid == 0 ? FMT1_REG_OFFSET : FMT2_REG_OFFSET;
|
|
||||||
Write32(OUT, fmtOffset + RV620_FMT1_BIT_DEPTH_CONTROL, 0);
|
|
||||||
|
|
||||||
Write32Mask(OUT, fmtOffset + RV620_FMT1_CONTROL, 0,
|
|
||||||
RV62_FMT_PIXEL_ENCODING);
|
|
||||||
// 4:4:4 encoding
|
|
||||||
|
|
||||||
Write32(OUT, fmtOffset + RV620_FMT1_CLAMP_CNTL, 0);
|
|
||||||
// disable color clamping
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* For Cards < r620 */
|
|
||||||
void
|
|
||||||
DACSetLegacy(uint8 dacIndex, uint32 crtid)
|
|
||||||
{
|
|
||||||
bool istv = false;
|
|
||||||
|
|
||||||
// BIG TODO : NTSC, PAL, ETC. We assume VGA for now
|
|
||||||
uint8 standard = FORMAT_VGA; /* VGA */
|
|
||||||
|
|
||||||
uint8 bandGap;
|
|
||||||
uint8 whiteFine;
|
|
||||||
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
|
|
||||||
DACSet(uint8 dacIndex, uint32 crtid)
|
|
||||||
{
|
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
|
||||||
|
|
||||||
TRACE("%s: dac %d to crt %d\n", __func__, dacIndex, crtid);
|
|
||||||
|
|
||||||
if (info.device_chipset < (RADEON_R600 | 0x20))
|
|
||||||
DACSetLegacy(dacIndex, crtid);
|
|
||||||
else
|
|
||||||
DACSetModern(dacIndex, crtid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* For Cards >= r620 */
|
|
||||||
void
|
|
||||||
DACPowerModern(uint8 dacIndex, int mode)
|
|
||||||
{
|
|
||||||
TRACE("%s: dacIndex: %d; mode: %d\n", __func__, dacIndex, mode);
|
|
||||||
|
|
||||||
uint32 dacOffset = dacIndex == 1 ? RV620_REG_DACB_OFFSET
|
|
||||||
: RV620_REG_DACA_OFFSET;
|
|
||||||
uint32 powerdown;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case RHD_POWER_ON:
|
|
||||||
TRACE("%s: dacIndex: %d; POWER_ON\n", __func__, dacIndex);
|
|
||||||
// TODO : SensedType Detection?
|
|
||||||
powerdown = 0;
|
|
||||||
if (!(Read32(OUT, dacOffset + RV620_DACA_ENABLE) & 0x01))
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_ENABLE, 0x1, 0xff);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_FORCE_OUTPUT_CNTL,
|
|
||||||
0x01, 0x01);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_POWERDOWN, 0x0, 0xff);
|
|
||||||
snooze(20);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_POWERDOWN,
|
|
||||||
powerdown, 0xFFFFFF00);
|
|
||||||
Write32(OUT, dacOffset + RV620_DACA_FORCE_OUTPUT_CNTL, 0x0);
|
|
||||||
Write32(OUT, dacOffset + RV620_DACA_SYNC_TRISTATE_CONTROL, 0x0);
|
|
||||||
return;
|
|
||||||
case RHD_POWER_RESET:
|
|
||||||
TRACE("%s: dacIndex: %d; POWER_RESET\n", __func__, dacIndex);
|
|
||||||
// No action
|
|
||||||
return;
|
|
||||||
case RHD_POWER_SHUTDOWN:
|
|
||||||
TRACE("%s: dacIndex: %d; POWER_SHUTDOWN\n", __func__, dacIndex);
|
|
||||||
default:
|
|
||||||
Write32(OUT, dacOffset + RV620_DACA_POWERDOWN, 0x01010100);
|
|
||||||
Write32(OUT, dacOffset + RV620_DACA_POWERDOWN, 0x01010101);
|
|
||||||
Write32(OUT, dacOffset + RV620_DACA_ENABLE, 0);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_FORCE_DATA, 0, 0xffff);
|
|
||||||
Write32Mask(OUT, dacOffset + RV620_DACA_FORCE_OUTPUT_CNTL,
|
|
||||||
0x701, 0x701);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* For Cards < r620 */
|
|
||||||
void
|
|
||||||
DACPowerLegacy(uint8 dacIndex, int mode)
|
|
||||||
{
|
|
||||||
uint32 dacOffset = dacIndex == 1 ? REG_DACB_OFFSET : REG_DACA_OFFSET;
|
|
||||||
uint32 powerdown;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case RHD_POWER_ON:
|
|
||||||
TRACE("%s: dacIndex: %d; POWER_ON\n", __func__, dacIndex);
|
|
||||||
// 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;
|
|
||||||
case RHD_POWER_RESET:
|
|
||||||
TRACE("%s: dacIndex: %d; POWER_RESET\n", __func__, dacIndex);
|
|
||||||
// No action
|
|
||||||
return;
|
|
||||||
case RHD_POWER_SHUTDOWN:
|
|
||||||
TRACE("%s: dacIndex: %d; POWER_SHUTDOWN\n", __func__, dacIndex);
|
|
||||||
default:
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_FORCE_DATA, 0, 0x0000FFFF);
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_FORCE_OUTPUT_CNTL,
|
|
||||||
0x0000701, 0x0000701);
|
|
||||||
Write32(OUT, dacOffset + DACA_POWERDOWN, 0x01010100);
|
|
||||||
Write32(OUT, dacOffset + DACA_POWERDOWN, 0x01010101);
|
|
||||||
Write32(OUT, dacOffset + DACA_ENABLE, 0);
|
|
||||||
Write32(OUT, dacOffset + DACA_ENABLE, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DACPower(uint8 dacIndex, int mode)
|
|
||||||
{
|
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
|
||||||
|
|
||||||
if (info.device_chipset < (RADEON_R600 | 0x20))
|
|
||||||
DACPowerLegacy(dacIndex, mode);
|
|
||||||
else
|
|
||||||
DACPowerModern(dacIndex, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DACAllIdle()
|
|
||||||
{
|
|
||||||
// This really doesn't do anything on DAC monitors
|
|
||||||
// Implimented for completeness
|
|
||||||
uint8 i;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
DACPower(i, RHD_POWER_RESET);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Alexander von Gluck, kallisti5@unixzen.com
|
|
||||||
*/
|
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
bool dac_sense(uint32 connector_id);
|
|
||||||
void DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine);
|
|
||||||
void DACSet(uint8 dacIndex, uint32 crtid);
|
|
||||||
void DACPower(uint8 dacIndex, int mode);
|
|
||||||
void DACAllIdle();
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1090,143 +1090,3 @@ display_crtc_power(uint8 crt_id, int command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
union crtc_source_param {
|
|
||||||
SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
|
|
||||||
SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
display_crtc_assign_encoder(uint8 crtc_id)
|
|
||||||
{
|
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
|
||||||
union crtc_source_param args;
|
|
||||||
uint8 frev;
|
|
||||||
uint8 crev;
|
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
|
||||||
|
|
||||||
if (atom_parse_cmd_header(gAtomContext, index, &frev, &crev)
|
|
||||||
!= B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint16 connector_index = gDisplay[crtc_id]->connector_index;
|
|
||||||
uint16 encoder_id = gConnector[connector_index]->encoder_object_id;
|
|
||||||
|
|
||||||
switch (frev) {
|
|
||||||
case 1:
|
|
||||||
switch (crev) {
|
|
||||||
case 1:
|
|
||||||
default:
|
|
||||||
args.v1.ucCRTC = crtc_id;
|
|
||||||
switch (encoder_id) {
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
|
||||||
args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
|
||||||
//if (radeon_encoder->devices
|
|
||||||
// & ATOM_DEVICE_LCD1_SUPPORT)
|
|
||||||
// args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
|
|
||||||
//else
|
|
||||||
args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_DDI:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
|
||||||
args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
|
||||||
//if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_TV_SUPPORT))
|
|
||||||
// args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
|
|
||||||
//else if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_CV_SUPPORT))
|
|
||||||
// args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
|
|
||||||
//else
|
|
||||||
args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
|
||||||
//if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_TV_SUPPORT))
|
|
||||||
// args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
|
|
||||||
//else if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_CV_SUPPORT))
|
|
||||||
// args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
|
|
||||||
//else
|
|
||||||
args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
args.v2.ucCRTC = crtc_id;
|
|
||||||
args.v2.ucEncodeMode
|
|
||||||
= display_get_encoder_mode(connector_index);
|
|
||||||
switch (encoder_id) {
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
|
||||||
ERROR("%s: DIG encoder not yet supported!\n",
|
|
||||||
__func__);
|
|
||||||
//dig = radeon_encoder->enc_priv;
|
|
||||||
//switch (dig->dig_encoder) {
|
|
||||||
// case 0:
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
|
||||||
// break;
|
|
||||||
// case 1:
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
|
||||||
// break;
|
|
||||||
// case 2:
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
|
|
||||||
// break;
|
|
||||||
// case 3:
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
|
|
||||||
// break;
|
|
||||||
// case 4:
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
|
|
||||||
// break;
|
|
||||||
// case 5:
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
|
||||||
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
|
||||||
//if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_TV_SUPPORT))
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
|
||||||
//else if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_CV_SUPPORT))
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
|
||||||
//else
|
|
||||||
args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
|
||||||
//if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_TV_SUPPORT))
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
|
||||||
//else if (radeon_encoder->active_device
|
|
||||||
// & (ATOM_DEVICE_CV_SUPPORT))
|
|
||||||
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
|
||||||
//else
|
|
||||||
args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR("%s: Unknown table version: %d, %d\n", __func__, frev, crev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
|
||||||
|
|
||||||
// TODO : encoder_crtc_scratch_regs?
|
|
||||||
}
|
|
||||||
|
@ -74,7 +74,6 @@ void display_crtc_fb_set_dce1(uint8 crtc_id, display_mode *mode);
|
|||||||
void display_crtc_set(uint8 crtc_id, display_mode *mode);
|
void display_crtc_set(uint8 crtc_id, display_mode *mode);
|
||||||
void display_crtc_set_dtd(uint8 crtc_id, display_mode *mode);
|
void display_crtc_set_dtd(uint8 crtc_id, display_mode *mode);
|
||||||
void display_crtc_power(uint8 crt_id, int command);
|
void display_crtc_power(uint8 crt_id, int command);
|
||||||
void display_crtc_assign_encoder(uint8 crt_id);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* RADEON_HD_DISPLAY_H */
|
#endif /* RADEON_HD_DISPLAY_H */
|
||||||
|
172
src/add-ons/accelerants/radeon_hd/encoder.cpp
Normal file
172
src/add-ons/accelerants/radeon_hd/encoder.cpp
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Alexander von Gluck, kallisti5@unixzen.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "accelerant_protos.h"
|
||||||
|
#include "accelerant.h"
|
||||||
|
#include "bios.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define TRACE_ENCODER
|
||||||
|
#ifdef TRACE_ENCODER
|
||||||
|
extern "C" void _sPrintf(const char *format, ...);
|
||||||
|
# define TRACE(x...) _sPrintf("radeon_hd: " x)
|
||||||
|
#else
|
||||||
|
# define TRACE(x...) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERROR(x...) _sPrintf("radeon_hd: " x)
|
||||||
|
|
||||||
|
|
||||||
|
union crtc_source_param {
|
||||||
|
SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
|
||||||
|
SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
encoder_assign_crtc(uint8 crtc_id)
|
||||||
|
{
|
||||||
|
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
||||||
|
union crtc_source_param args;
|
||||||
|
uint8 frev;
|
||||||
|
uint8 crev;
|
||||||
|
|
||||||
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
|
if (atom_parse_cmd_header(gAtomContext, index, &frev, &crev)
|
||||||
|
!= B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint16 connector_index = gDisplay[crtc_id]->connector_index;
|
||||||
|
uint16 encoder_id = gConnector[connector_index]->encoder_object_id;
|
||||||
|
|
||||||
|
switch (frev) {
|
||||||
|
case 1:
|
||||||
|
switch (crev) {
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
args.v1.ucCRTC = crtc_id;
|
||||||
|
switch (encoder_id) {
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||||
|
args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||||
|
//if (radeon_encoder->devices
|
||||||
|
// & ATOM_DEVICE_LCD1_SUPPORT)
|
||||||
|
// args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
|
||||||
|
//else
|
||||||
|
args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_DDI:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||||
|
args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||||
|
//if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_TV_SUPPORT))
|
||||||
|
// args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
|
||||||
|
//else if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_CV_SUPPORT))
|
||||||
|
// args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
|
||||||
|
//else
|
||||||
|
args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
||||||
|
//if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_TV_SUPPORT))
|
||||||
|
// args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
|
||||||
|
//else if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_CV_SUPPORT))
|
||||||
|
// args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
|
||||||
|
//else
|
||||||
|
args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
args.v2.ucCRTC = crtc_id;
|
||||||
|
args.v2.ucEncodeMode
|
||||||
|
= display_get_encoder_mode(connector_index);
|
||||||
|
switch (encoder_id) {
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
|
ERROR("%s: DIG encoder not yet supported!\n",
|
||||||
|
__func__);
|
||||||
|
//dig = radeon_encoder->enc_priv;
|
||||||
|
//switch (dig->dig_encoder) {
|
||||||
|
// case 0:
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
||||||
|
// break;
|
||||||
|
// case 1:
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
||||||
|
// break;
|
||||||
|
// case 2:
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
|
||||||
|
// break;
|
||||||
|
// case 3:
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
|
||||||
|
// break;
|
||||||
|
// case 4:
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
|
||||||
|
// break;
|
||||||
|
// case 5:
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||||
|
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||||
|
//if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_TV_SUPPORT))
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
||||||
|
//else if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_CV_SUPPORT))
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
||||||
|
//else
|
||||||
|
args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
|
||||||
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
||||||
|
//if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_TV_SUPPORT))
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
||||||
|
//else if (radeon_encoder->active_device
|
||||||
|
// & (ATOM_DEVICE_CV_SUPPORT))
|
||||||
|
// args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
||||||
|
//else
|
||||||
|
args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("%s: Unknown table version: %d, %d\n", __func__, frev, crev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||||
|
|
||||||
|
// TODO : encoder_crtc_scratch_regs?
|
||||||
|
}
|
15
src/add-ons/accelerants/radeon_hd/encoder.h
Normal file
15
src/add-ons/accelerants/radeon_hd/encoder.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Alexander von Gluck, kallisti5@unixzen.com
|
||||||
|
*/
|
||||||
|
#ifndef RADEON_HD_ENCODER_H
|
||||||
|
#define RADEON_HD_ENCODER_H
|
||||||
|
|
||||||
|
|
||||||
|
void encoder_assign_crtc(uint8 crt_id);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* RADEON_HD_ENCODER_H */
|
@ -1,267 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Alexander von Gluck, kallisti5@unixzen.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "accelerant_protos.h"
|
|
||||||
#include "accelerant.h"
|
|
||||||
#include "utility.h"
|
|
||||||
#include "lvds.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_LVDS
|
|
||||||
#ifdef TRACE_LVDS
|
|
||||||
extern "C" void _sPrintf(const char *format, ...);
|
|
||||||
# define TRACE(x...) _sPrintf("radeon_hd: " x)
|
|
||||||
#else
|
|
||||||
# define TRACE(x...) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Static microvoltage values taken from Xorg driver
|
|
||||||
static struct R5xxTMDSBMacro {
|
|
||||||
uint16 device;
|
|
||||||
uint32 macroSingle;
|
|
||||||
uint32 macroDual;
|
|
||||||
} R5xxTMDSBMacro[] = {
|
|
||||||
/*
|
|
||||||
* this list isn't complete yet.
|
|
||||||
* Some more values for dual need to be dug up
|
|
||||||
*/
|
|
||||||
{ 0x7104, 0x00F20616, 0x00F20616 }, // R520
|
|
||||||
{ 0x7142, 0x00F2061C, 0x00F2061C }, // RV515
|
|
||||||
{ 0x7145, 0x00F1061D, 0x00F2061D },
|
|
||||||
{ 0x7146, 0x00F1061D, 0x00F1061D }, // RV515
|
|
||||||
{ 0x7147, 0x0082041D, 0x0082041D }, // RV505
|
|
||||||
{ 0x7149, 0x00F1061D, 0x00D2061D },
|
|
||||||
{ 0x7152, 0x00F2061C, 0x00F2061C }, // RV515
|
|
||||||
{ 0x7183, 0x00B2050C, 0x00B2050C }, // RV530
|
|
||||||
{ 0x71C0, 0x00F1061F, 0x00f2061D },
|
|
||||||
{ 0x71C1, 0x0062041D, 0x0062041D }, // RV535
|
|
||||||
{ 0x71C2, 0x00F1061D, 0x00F2061D }, // RV530
|
|
||||||
{ 0x71C5, 0x00D1061D, 0x00D2061D },
|
|
||||||
{ 0x71C6, 0x00F2061D, 0x00F2061D }, // RV530
|
|
||||||
{ 0x71D2, 0x00F10610, 0x00F20610 }, // RV530: atombios uses 0x00F1061D
|
|
||||||
{ 0x7249, 0x00F1061D, 0x00F1061D }, // R580
|
|
||||||
{ 0x724B, 0x00F10610, 0x00F10610 }, // R580: atombios uses 0x00F1061D
|
|
||||||
{ 0x7280, 0x0042041F, 0x0042041F }, // RV570
|
|
||||||
{ 0x7288, 0x0042041F, 0x0042041F }, // RV570
|
|
||||||
{ 0x791E, 0x0001642F, 0x0001642F }, // RS690
|
|
||||||
{ 0x791F, 0x0001642F, 0x0001642F }, // RS690
|
|
||||||
{ 0x9400, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x9401, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x9402, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x9403, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x9405, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x940A, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x940B, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0x940F, 0x00020213, 0x00020213 }, // R600
|
|
||||||
{ 0, 0, 0 } /* End marker */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct RV6xxTMDSBMacro {
|
|
||||||
uint16 device;
|
|
||||||
uint32 macro;
|
|
||||||
uint32 tx;
|
|
||||||
uint32 preEmphasis;
|
|
||||||
} RV6xxTMDSBMacro[] = {
|
|
||||||
{ 0x94C1, 0x01030311, 0x10001A00, 0x01801015}, /* RV610 */
|
|
||||||
{ 0x94C3, 0x01030311, 0x10001A00, 0x01801015}, /* RV610 */
|
|
||||||
{ 0x9501, 0x0533041A, 0x020010A0, 0x41002045}, /* RV670 */
|
|
||||||
{ 0x9505, 0x0533041A, 0x020010A0, 0x41002045}, /* RV670 */
|
|
||||||
{ 0x950F, 0x0533041A, 0x020010A0, 0x41002045}, /* R680 */
|
|
||||||
{ 0x9587, 0x01030311, 0x10001C00, 0x01C01011}, /* RV630 */
|
|
||||||
{ 0x9588, 0x01030311, 0x10001C00, 0x01C01011}, /* RV630 */
|
|
||||||
{ 0x9589, 0x01030311, 0x10001C00, 0x01C01011}, /* RV630 */
|
|
||||||
{ 0, 0, 0, 0} /* End marker */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LVDSVoltageControl(uint8 lvdsIndex)
|
|
||||||
{
|
|
||||||
bool dualLink = false; // TODO : DualLink
|
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
|
||||||
|
|
||||||
// TODO : Special RS690 RS600 IGP oneoffs
|
|
||||||
|
|
||||||
if (info.device_chipset < (RADEON_R600 | 0x70))
|
|
||||||
Write32Mask(OUT, LVTMA_REG_TEST_OUTPUT, 0x00100000, 0x00100000);
|
|
||||||
|
|
||||||
// Micromanage voltages
|
|
||||||
if (info.device_chipset < (RADEON_R600 | 0x10)) {
|
|
||||||
for (uint32 i = 0; R5xxTMDSBMacro[i].device; i++) {
|
|
||||||
if (R5xxTMDSBMacro[i].device == info.device_id) {
|
|
||||||
if (dualLink) {
|
|
||||||
Write32(OUT, LVTMA_MACRO_CONTROL,
|
|
||||||
R5xxTMDSBMacro[i].macroDual);
|
|
||||||
} else {
|
|
||||||
Write32(OUT, LVTMA_MACRO_CONTROL,
|
|
||||||
R5xxTMDSBMacro[i].macroSingle);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("%s : unhandled chipset 0x%X\n", __func__, info.device_id);
|
|
||||||
} else {
|
|
||||||
for (uint32 i = 0; RV6xxTMDSBMacro[i].device; i++) {
|
|
||||||
if (RV6xxTMDSBMacro[i].device == info.device_id) {
|
|
||||||
Write32(OUT, LVTMA_MACRO_CONTROL, RV6xxTMDSBMacro[i].macro);
|
|
||||||
Write32(OUT, LVTMA_TRANSMITTER_ADJUST,
|
|
||||||
RV6xxTMDSBMacro[i].tx);
|
|
||||||
Write32(OUT, LVTMA_PREEMPHASIS_CONTROL,
|
|
||||||
RV6xxTMDSBMacro[i].preEmphasis);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("%s : unhandled chipset 0x%X\n", __func__, info.device_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LVDSPower(uint8 lvdsIndex, int command)
|
|
||||||
{
|
|
||||||
bool dualLink = false; // TODO : dualLink
|
|
||||||
|
|
||||||
if (lvdsIndex == 0) {
|
|
||||||
TRACE("LVTMA not yet supported :(\n");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Select TMDSB (which is on LVDS)
|
|
||||||
Write32Mask(OUT, LVTMA_MODE, 0x00000001, 0x00000001);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (command) {
|
|
||||||
case RHD_POWER_ON:
|
|
||||||
TRACE("%s: LVDS %d Power On\n", __func__, lvdsIndex);
|
|
||||||
Write32Mask(OUT, LVTMA_CNTL, 0x1, 0x00000001);
|
|
||||||
|
|
||||||
if (dualLink) {
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_ENABLE,
|
|
||||||
0x00003E3E, 0x00003E3E);
|
|
||||||
} else {
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_ENABLE,
|
|
||||||
0x0000003E, 0x00003E3E);
|
|
||||||
}
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0x00000001, 0x00000001);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0, 0x00000002);
|
|
||||||
// TODO : Enable HDMI
|
|
||||||
return;
|
|
||||||
|
|
||||||
case RHD_POWER_RESET:
|
|
||||||
TRACE("%s: LVDS %d Power Reset\n", __func__, lvdsIndex);
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_ENABLE, 0, 0x00003E3E);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case RHD_POWER_SHUTDOWN:
|
|
||||||
default:
|
|
||||||
TRACE("%s: LVDS %d Power Shutdown\n", __func__, lvdsIndex);
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0x00000002, 0x00000002);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0, 0x00000001);
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_ENABLE, 0, 0x00003E3E);
|
|
||||||
Write32Mask(OUT, LVTMA_CNTL, 0, 0x00000001);
|
|
||||||
// TODO : Disable HDMI
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
LVDSSet(uint8 lvdsIndex, display_mode *mode)
|
|
||||||
{
|
|
||||||
TRACE("%s: LVDS %d Set\n", __func__, lvdsIndex);
|
|
||||||
|
|
||||||
uint16 crtid = 0; // TODO : assume CRT0
|
|
||||||
|
|
||||||
if (lvdsIndex == 0) {
|
|
||||||
TRACE("LVTMA not yet supported :(\n");
|
|
||||||
return B_ERROR;
|
|
||||||
} else {
|
|
||||||
// Select TMDSB (which is on LVDS)
|
|
||||||
Write32Mask(OUT, LVTMA_MODE, 0x00000001, 0x00000001);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear HPD events
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0, 0x0000000C);
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_ENABLE, 0, 0x00070000);
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_CNTL, 0, 0x00000010);
|
|
||||||
|
|
||||||
// Disable LVDS (TMDSB) transmitter
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_ENABLE, 0, 0x00003E3E);
|
|
||||||
|
|
||||||
// Reset dither bits
|
|
||||||
Write32Mask(OUT, LVTMA_BIT_DEPTH_CONTROL, 0, 0x00010101);
|
|
||||||
Write32Mask(OUT, LVTMA_BIT_DEPTH_CONTROL, LVTMA_DITHER_RESET_BIT,
|
|
||||||
LVTMA_DITHER_RESET_BIT);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, LVTMA_BIT_DEPTH_CONTROL, 0, LVTMA_DITHER_RESET_BIT);
|
|
||||||
Write32Mask(OUT, LVTMA_BIT_DEPTH_CONTROL, 0, 0xF0000000);
|
|
||||||
// Undocumented depth control bit from Xorg
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_CNTL, 0x00001000, 0x00011000);
|
|
||||||
// Reset phase for vsync and use RGB color
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_SOURCE_SELECT, crtid, 0x00010101);
|
|
||||||
// Assign to CRTC
|
|
||||||
|
|
||||||
Write32(OUT, LVTMA_COLOR_FORMAT, 0);
|
|
||||||
|
|
||||||
// TODO : Detect DualLink via SynthClock?
|
|
||||||
Write32Mask(OUT, LVTMA_CNTL, 0, 0x01000000);
|
|
||||||
|
|
||||||
// TODO : only > R600 - disable split mode
|
|
||||||
Write32Mask(OUT, LVTMA_CNTL, 0, 0x20000000);
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_FORCE_OUTPUT_CNTL, 0, 0x00000001);
|
|
||||||
// Disable force data
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_DCBALANCER_CONTROL, 0x00000001, 0x00000001);
|
|
||||||
// Enable DC balancer
|
|
||||||
|
|
||||||
LVDSVoltageControl(lvdsIndex);
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0x00000010, 0x00000010);
|
|
||||||
// use IDCLK
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0x20000000, 0x20000000);
|
|
||||||
// use clock selected by next write
|
|
||||||
|
|
||||||
// TODO : coherent mode?
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0, 0x10000000);
|
|
||||||
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0, 0x03FF0000);
|
|
||||||
// Clear current LVDS clock
|
|
||||||
|
|
||||||
// Reset PLL's
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0x00000002, 0x00000002);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, LVTMA_TRANSMITTER_CONTROL, 0, 0x00000002);
|
|
||||||
snooze(20);
|
|
||||||
|
|
||||||
// Restart LVDS data sync
|
|
||||||
Write32Mask(OUT, LVTMA_DATA_SYNCHRONIZATION, 0x00000001, 0x00000001);
|
|
||||||
Write32Mask(OUT, LVTMA_DATA_SYNCHRONIZATION, 0x00000100, 0x00000100);
|
|
||||||
snooze(20);
|
|
||||||
Write32Mask(OUT, LVTMA_DATA_SYNCHRONIZATION, 0, 0x00000001);
|
|
||||||
|
|
||||||
// TODO : Set HDMI mode
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LVDSAllIdle()
|
|
||||||
{
|
|
||||||
LVDSPower(1, RHD_POWER_RESET);
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Alexander von Gluck, kallisti5@unixzen.com
|
|
||||||
*/
|
|
||||||
#ifndef RADEON_HD_LVDS_H
|
|
||||||
#define RADEON_HD_LVDS_H
|
|
||||||
|
|
||||||
|
|
||||||
#define LVTMA_DATA_SYNCHRONIZATION LVTMA_R600_DATA_SYNCHRONIZATION
|
|
||||||
#define LVTMA_PWRSEQ_REF_DIV LVTMA_R600_PWRSEQ_REF_DIV
|
|
||||||
#define LVTMA_PWRSEQ_DELAY1 LVTMA_R600_PWRSEQ_DELAY1
|
|
||||||
#define LVTMA_PWRSEQ_DELAY2 LVTMA_R600_PWRSEQ_DELAY2
|
|
||||||
#define LVTMA_PWRSEQ_CNTL LVTMA_R600_PWRSEQ_CNTL
|
|
||||||
#define LVTMA_PWRSEQ_STATE LVTMA_R600_PWRSEQ_STATE
|
|
||||||
#define LVTMA_LVDS_DATA_CNTL LVTMA_R600_LVDS_DATA_CNTL
|
|
||||||
#define LVTMA_MODE LVTMA_R600_MODE
|
|
||||||
#define LVTMA_TRANSMITTER_ENABLE LVTMA_R600_TRANSMITTER_ENABLE
|
|
||||||
#define LVTMA_MACRO_CONTROL LVTMA_R600_MACRO_CONTROL
|
|
||||||
#define LVTMA_TRANSMITTER_CONTROL LVTMA_R600_TRANSMITTER_CONTROL
|
|
||||||
#define LVTMA_REG_TEST_OUTPUT LVTMA_R600_REG_TEST_OUTPUT
|
|
||||||
#define LVTMA_BL_MOD_CNTL LVTMA_R600_BL_MOD_CNTL
|
|
||||||
#define LVTMA_DITHER_RESET_BIT 0x02000000
|
|
||||||
|
|
||||||
|
|
||||||
void LVDSVoltageControl(uint8 lvdsIndex);
|
|
||||||
void LVDSPower(uint8 lvdsIndex, int command);
|
|
||||||
status_t LVDSSet(uint8 lvdsIndex, display_mode *mode);
|
|
||||||
void LVDSAllIdle();
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* RADEON_HD_LVDS_H */
|
|
@ -113,11 +113,11 @@ radeon_set_display_mode(display_mode *mode)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 connector_index = gDisplay[id]->connector_index;
|
// uint32 connector_index = gDisplay[id]->connector_index;
|
||||||
// uint32 connector_type = gConnector[connector_index]->connector_type;
|
// uint32 connector_type = gConnector[connector_index]->connector_type;
|
||||||
uint32 encoder_type = gConnector[connector_index]->encoder_type;
|
// uint32 encoder_type = gConnector[connector_index]->encoder_type;
|
||||||
|
|
||||||
display_crtc_assign_encoder(id);
|
encoder_assign_crtc(id);
|
||||||
|
|
||||||
// TODO : the first id is the pll we use... this won't work for
|
// TODO : the first id is the pll we use... this won't work for
|
||||||
// more then two monitors
|
// more then two monitors
|
||||||
@ -125,45 +125,16 @@ radeon_set_display_mode(display_mode *mode)
|
|||||||
|
|
||||||
// Program CRT Controller
|
// Program CRT Controller
|
||||||
display_crtc_set_dtd(id, mode);
|
display_crtc_set_dtd(id, mode);
|
||||||
//display_crtc_fb_set_dce1(id, mode);
|
display_crtc_fb_set_dce1(id, mode);
|
||||||
display_crtc_fb_set_legacy(id, mode);
|
//display_crtc_fb_set_legacy(id, mode);
|
||||||
display_crtc_scale(id, mode);
|
display_crtc_scale(id, mode);
|
||||||
|
|
||||||
// Program connector controllers
|
|
||||||
switch (encoder_type) {
|
|
||||||
case VIDEO_ENCODER_DAC:
|
|
||||||
case VIDEO_ENCODER_TVDAC:
|
|
||||||
// DACSet(connector_index, id);
|
|
||||||
break;
|
|
||||||
case VIDEO_ENCODER_TMDS:
|
|
||||||
// TMDSSet(connector_index, mode);
|
|
||||||
break;
|
|
||||||
case VIDEO_ENCODER_LVDS:
|
|
||||||
// LVDSSet(connector_index, mode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Power CRT Controller
|
// Power CRT Controller
|
||||||
display_crtc_blank(id, ATOM_DISABLE);
|
display_crtc_blank(id, ATOM_DISABLE);
|
||||||
display_crtc_power(id, ATOM_ENABLE);
|
display_crtc_power(id, ATOM_ENABLE);
|
||||||
|
|
||||||
//PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
//PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
||||||
|
|
||||||
// Power connector controllers
|
|
||||||
switch (encoder_type) {
|
|
||||||
case VIDEO_ENCODER_DAC:
|
|
||||||
case VIDEO_ENCODER_TVDAC:
|
|
||||||
// DACPower(connector_index, RHD_POWER_ON);
|
|
||||||
break;
|
|
||||||
case VIDEO_ENCODER_TMDS:
|
|
||||||
// TMDSPower(connector_index, RHD_POWER_ON);
|
|
||||||
break;
|
|
||||||
case VIDEO_ENCODER_LVDS:
|
|
||||||
// LVDSSet(connector_index, mode);
|
|
||||||
// LVDSPower(connector_index, RHD_POWER_ON);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
display_crtc_lock(id, ATOM_DISABLE);
|
display_crtc_lock(id, ATOM_DISABLE);
|
||||||
// commit
|
// commit
|
||||||
}
|
}
|
||||||
|
@ -221,8 +221,8 @@ pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
|
|||||||
args.v3.ucMiscInfo = (pll_id << 2);
|
args.v3.ucMiscInfo = (pll_id << 2);
|
||||||
// if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
|
// if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
|
||||||
// args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
|
// args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
|
||||||
args.v3.ucTransmitterId = crtc_id;
|
args.v3.ucTransmitterId
|
||||||
// TODO : transmitter id is now CRTC id?
|
= gConnector[connector_index]->encoder_object_id;
|
||||||
args.v3.ucEncoderMode = display_get_encoder_mode(connector_index);
|
args.v3.ucEncoderMode = display_get_encoder_mode(connector_index);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Alexander von Gluck, kallisti5@unixzen.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "accelerant_protos.h"
|
|
||||||
#include "accelerant.h"
|
|
||||||
#include "utility.h"
|
|
||||||
#include "tmds.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_TMDS
|
|
||||||
#ifdef TRACE_TMDS
|
|
||||||
extern "C" void _sPrintf(const char *format, ...);
|
|
||||||
# define TRACE(x...) _sPrintf("radeon_hd: " x)
|
|
||||||
#else
|
|
||||||
# define TRACE(x...) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* From Xorg Driver
|
|
||||||
* This information is not provided in an atombios data table.
|
|
||||||
*/
|
|
||||||
static struct R5xxTMDSAMacro {
|
|
||||||
uint16 device;
|
|
||||||
uint32 macro;
|
|
||||||
} R5xxTMDSAMacro[] = {
|
|
||||||
{ 0x7104, 0x00C00414 }, /* R520 */
|
|
||||||
{ 0x7142, 0x00A00415 }, /* RV515 */
|
|
||||||
{ 0x7145, 0x00A00416 }, /* M54 */
|
|
||||||
{ 0x7146, 0x00C0041F }, /* RV515 */
|
|
||||||
{ 0x7147, 0x00C00418 }, /* RV505 */
|
|
||||||
{ 0x7149, 0x00800416 }, /* M56 */
|
|
||||||
{ 0x7152, 0x00A00415 }, /* RV515 */
|
|
||||||
{ 0x7183, 0x00600412 }, /* RV530 */
|
|
||||||
{ 0x71C1, 0x00C0041F }, /* RV535 */
|
|
||||||
{ 0x71C2, 0x00A00416 }, /* RV530 */
|
|
||||||
{ 0x71C4, 0x00A00416 }, /* M56 */
|
|
||||||
{ 0x71C5, 0x00A00416 }, /* M56 */
|
|
||||||
{ 0x71C6, 0x00A00513 }, /* RV530 */
|
|
||||||
{ 0x71D2, 0x00A00513 }, /* RV530 */
|
|
||||||
{ 0x71D5, 0x00A00513 }, /* M66 */
|
|
||||||
{ 0x7249, 0x00A00513 }, /* R580 */
|
|
||||||
{ 0x724B, 0x00A00513 }, /* R580 */
|
|
||||||
{ 0x7280, 0x00C0041F }, /* RV570 */
|
|
||||||
{ 0x7288, 0x00C0041F }, /* RV570 */
|
|
||||||
{ 0x9400, 0x00910419 }, /* R600: */
|
|
||||||
{ 0, 0} /* End marker */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct Rv6xxTMDSAMacro {
|
|
||||||
uint16 device;
|
|
||||||
uint32 pll;
|
|
||||||
uint32 tx;
|
|
||||||
} Rv6xxTMDSAMacro[] = {
|
|
||||||
{ 0x94C1, 0x00010416, 0x00010308 }, /* RV610 */
|
|
||||||
{ 0x94C3, 0x00010416, 0x00010308 }, /* RV610 */
|
|
||||||
{ 0x9501, 0x00010416, 0x00010308 }, /* RV670: != atombios */
|
|
||||||
{ 0x9505, 0x00010416, 0x00010308 }, /* RV670: != atombios */
|
|
||||||
{ 0x950F, 0x00010416, 0x00010308 }, /* R680 : != atombios */
|
|
||||||
{ 0x9581, 0x00030410, 0x00301044 }, /* M76 */
|
|
||||||
{ 0x9587, 0x00010416, 0x00010308 }, /* RV630 */
|
|
||||||
{ 0x9588, 0x00010416, 0x00010388 }, /* RV630 */
|
|
||||||
{ 0x9589, 0x00010416, 0x00010388 }, /* RV630 */
|
|
||||||
{ 0, 0, 0} /* End marker */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TMDSVoltageControl(uint8 tmdsIndex)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
|
||||||
|
|
||||||
if (info.device_chipset < (RADEON_R600 | 0x10)) {
|
|
||||||
for (i = 0; R5xxTMDSAMacro[i].device; i++) {
|
|
||||||
if (R5xxTMDSAMacro[i].device == info.device_id) {
|
|
||||||
Write32(OUT, TMDSA_MACRO_CONTROL, R5xxTMDSAMacro[i].macro);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("%s : unhandled chipset 0x%X\n", __func__, info.device_id);
|
|
||||||
} else {
|
|
||||||
for (i = 0; Rv6xxTMDSAMacro[i].device; i++) {
|
|
||||||
if (Rv6xxTMDSAMacro[i].device == info.device_id) {
|
|
||||||
Write32(OUT, TMDSA_PLL_ADJUST, Rv6xxTMDSAMacro[i].pll);
|
|
||||||
Write32(OUT, TMDSA_TRANSMITTER_ADJUST, Rv6xxTMDSAMacro[i].tx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("%s : unhandled chipset 0x%X\n", __func__, info.device_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TMDSSense(uint8 tmdsIndex)
|
|
||||||
{
|
|
||||||
// For now radeon cards only have TMDSA and no TMDSB
|
|
||||||
|
|
||||||
// Backup current TMDS values
|
|
||||||
uint32 loadDetect = Read32(OUT, TMDSA_LOAD_DETECT);
|
|
||||||
|
|
||||||
// Call TMDS load detect on TMDSA
|
|
||||||
Write32Mask(OUT, TMDSA_LOAD_DETECT, 0x00000001, 0x00000001);
|
|
||||||
snooze(1);
|
|
||||||
|
|
||||||
// Check result of TMDS load detect
|
|
||||||
bool result = Read32(OUT, TMDSA_LOAD_DETECT) & 0x00000010;
|
|
||||||
|
|
||||||
// Restore saved value
|
|
||||||
Write32Mask(OUT, TMDSA_LOAD_DETECT, loadDetect, 0x00000001);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
TMDSPower(uint8 tmdsIndex, int command)
|
|
||||||
{
|
|
||||||
// For now radeon cards only have TMDSA and no TMDSB
|
|
||||||
switch (command) {
|
|
||||||
case RHD_POWER_ON:
|
|
||||||
{
|
|
||||||
TRACE("%s: TMDS %d Power On\n", __func__, tmdsIndex);
|
|
||||||
Write32Mask(OUT, TMDSA_CNTL, 0x1, 0x00000001);
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0x00000001, 0x00000001);
|
|
||||||
snooze(20);
|
|
||||||
|
|
||||||
// Reset transmitter
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0x00000002, 0x00000002);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0, 0x00000002);
|
|
||||||
|
|
||||||
snooze(30);
|
|
||||||
|
|
||||||
// Restart data sync
|
|
||||||
// TODO : <R600
|
|
||||||
Write32Mask(OUT, TMDSA_DATA_SYNCHRONIZATION_R600,
|
|
||||||
0x00000001, 0x00000001);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, TMDSA_DATA_SYNCHRONIZATION_R600,
|
|
||||||
0x00000100, 0x00000100);
|
|
||||||
Write32Mask(OUT, TMDSA_DATA_SYNCHRONIZATION_R600, 0, 0x00000001);
|
|
||||||
|
|
||||||
// TODO : DualLink, for now we assume not.
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_ENABLE, 0x0000001F, 0x00001F1F);
|
|
||||||
|
|
||||||
// TODO : HdmiEnable true
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
case RHD_POWER_RESET:
|
|
||||||
{
|
|
||||||
TRACE("%s: TMDS %d Power Reset\n", __func__, tmdsIndex);
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_ENABLE, 0, 0x00001F1F);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
case RHD_POWER_SHUTDOWN:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0x00000002, 0x00000002);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0, 0x00000001);
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_ENABLE, 0, 0x00001F1F);
|
|
||||||
Write32Mask(OUT, TMDSA_CNTL, 0, 0x00000001);
|
|
||||||
// TODO : HdmiEnable false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
TMDSSet(uint8 tmdsIndex, display_mode *mode)
|
|
||||||
{
|
|
||||||
TRACE("%s: TMDS %d Set\n", __func__, tmdsIndex);
|
|
||||||
|
|
||||||
// Clear HPD events
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0, 0x0000000C);
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_ENABLE, 0, 0x00070000);
|
|
||||||
Write32Mask(OUT, TMDSA_CNTL, 0, 0x00000010);
|
|
||||||
|
|
||||||
// Disable transmitter
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_ENABLE, 0, 0x00001D1F);
|
|
||||||
|
|
||||||
// Disable bit reduction and reset dither
|
|
||||||
Write32Mask(OUT, TMDSA_BIT_DEPTH_CONTROL, 0, 0x00010101);
|
|
||||||
// TODO : <R600
|
|
||||||
Write32Mask(OUT, TMDSA_BIT_DEPTH_CONTROL, 0x02000000, 0x02000000);
|
|
||||||
snooze(2);
|
|
||||||
Write32Mask(OUT, TMDSA_BIT_DEPTH_CONTROL, 0, 0x02000000);
|
|
||||||
|
|
||||||
// Reset phase on vsync
|
|
||||||
Write32Mask(OUT, TMDSA_CNTL, 0x00001000, 0x00011000);
|
|
||||||
// TODO : for now we assume crt 0, needs refactoring
|
|
||||||
Write32Mask(OUT, TMDSA_SOURCE_SELECT, 0, 0x00010101);
|
|
||||||
|
|
||||||
Write32(OUT, TMDSA_COLOR_FORMAT, 0);
|
|
||||||
|
|
||||||
// Set single link for now
|
|
||||||
// TODO : SynthClock > 165000 this is DualLink
|
|
||||||
Write32Mask(OUT, TMDSA_CNTL, 0, 0x01000000);
|
|
||||||
|
|
||||||
// Disable force data
|
|
||||||
Write32Mask(OUT, TMDSA_FORCE_OUTPUT_CNTL, 0, 0x00000001);
|
|
||||||
|
|
||||||
// Enable DC balancer
|
|
||||||
Write32Mask(OUT, TMDSA_DCBALANCER_CONTROL, 0x00000001, 0x00000001);
|
|
||||||
|
|
||||||
TMDSVoltageControl(tmdsIndex);
|
|
||||||
|
|
||||||
// USE IDCLK
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0x00000010, 0x00000010);
|
|
||||||
|
|
||||||
// TODO : if coherent? For now lets asume false
|
|
||||||
Write32Mask(OUT, TMDSA_TRANSMITTER_CONTROL, 0x10000000, 0x10000000);
|
|
||||||
|
|
||||||
// TODO : HdmiSetMode(mode)
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TMDSAllIdle()
|
|
||||||
{
|
|
||||||
TMDSPower(0, RHD_POWER_RESET);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Alexander von Gluck, kallisti5@unixzen.com
|
|
||||||
*/
|
|
||||||
#ifndef RADEON_HD_TMDS_H
|
|
||||||
#define RADEON_HD_TMDS_H
|
|
||||||
|
|
||||||
|
|
||||||
void TMDSVoltageControl(uint8 tmdsIndex);
|
|
||||||
bool TMDSSense(uint8 tmdsIndex);
|
|
||||||
status_t TMDSPower(uint8 tmdsIndex, int command);
|
|
||||||
status_t TMDSSet(uint8 tmdsIndex, display_mode *mode);
|
|
||||||
void TMDSAllIdle();
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user