Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1320 → Rev 1321

/drivers/video/drm/radeon/atom.c
263,10 → 263,10
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
val = gctx->scratch[((gctx->fb_base + idx) / 4)];
if (print)
DEBUG("FB[0x%02X]", idx);
printk(KERN_INFO "FB access is not implemented.\n");
return 0;
break;
case ATOM_ARG_IMM:
switch (align) {
case ATOM_SRC_DWORD:
488,9 → 488,9
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
DEBUG("FB[0x%02X]", idx);
printk(KERN_INFO "FB access is not implemented.\n");
return;
break;
case ATOM_ARG_PLL:
idx = U8(*ptr);
(*ptr)++;
1214,3 → 1214,28
*crev = CU8(idx + 3);
return;
}
 
int atom_allocate_fb_scratch(struct atom_context *ctx)
{
int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
uint16_t data_offset;
int usage_bytes;
struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
 
atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
 
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
 
DRM_DEBUG("atom firmware requested %08x %dkb\n",
firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
 
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
if (usage_bytes == 0)
usage_bytes = 20 * 1024;
/* allocate some scratch memory */
ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
if (!ctx->scratch)
return -ENOMEM;
return 0;
}
/drivers/video/drm/radeon/atom.h
132,6 → 132,7
uint8_t shift;
int cs_equal, cs_above;
int io_mode;
uint32_t *scratch;
};
 
extern int atom_debug;
142,6 → 143,7
void atom_destroy(struct atom_context *);
void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
int atom_allocate_fb_scratch(struct atom_context *ctx);
#include "atom-types.h"
#include "atombios.h"
#include "ObjectID.h"
/drivers/video/drm/radeon/atombios.h
2680,7 → 2680,7
typedef struct _ATOM_HPD_INT_RECORD {
ATOM_COMMON_RECORD_HEADER sheader;
UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */
UCHAR ucPluggged_PinState;
UCHAR ucPlugged_PinState;
} ATOM_HPD_INT_RECORD;
 
typedef struct _ATOM_OUTPUT_PROTECTION_RECORD {
/drivers/video/drm/radeon/atombios_crtc.c
241,6 → 241,7
{
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
switch (mode) {
case DRM_MODE_DPMS_ON:
248,6 → 249,7
if (ASIC_IS_DCE3(rdev))
atombios_enable_crtc_memreq(crtc, 1);
atombios_blank_crtc(crtc, 0);
radeon_crtc_load_lut(crtc);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
258,11 → 260,7
atombios_enable_crtc(crtc, 0);
break;
}
 
if (mode != DRM_MODE_DPMS_OFF) {
radeon_crtc_load_lut(crtc);
}
}
 
static void
atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
457,9 → 455,8
if (encoder->encoder_type !=
DRM_MODE_ENCODER_DAC)
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
if (!ASIC_IS_AVIVO(rdev)
&& (encoder->encoder_type ==
DRM_MODE_ENCODER_LVDS))
if (encoder->encoder_type ==
DRM_MODE_ENCODER_LVDS)
pll_flags |= RADEON_PLL_USE_REF_DIV;
}
radeon_encoder = to_radeon_encoder(encoder);
500,6 → 497,16
else
pll = &rdev->clock.p2pll;
 
if (ASIC_IS_AVIVO(rdev)) {
if (radeon_new_pll)
radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
else
radeon_compute_pll(pll, adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
} else
radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
 
576,15 → 583,20
struct radeon_device *rdev = dev->dev_private;
struct radeon_framebuffer *radeon_fb;
struct drm_gem_object *obj;
struct drm_radeon_gem_object *obj_priv;
struct radeon_bo *rbo;
uint64_t fb_location;
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
int r;
 
if (!crtc->fb)
return -EINVAL;
/* no fb bound */
if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
return 0;
}
 
radeon_fb = to_radeon_framebuffer(crtc->fb);
 
/* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj;
obj_priv = obj->driver_private;
 
593,6 → 605,7
// }
 
fb_location = rdev->mc.vram_location;
tiling_flags = 0;
 
switch (crtc->fb->bits_per_pixel) {
case 8:
622,13 → 635,11
return -EINVAL;
}
 
// radeon_object_get_tiling_flags(obj->driver_private,
// &tiling_flags, NULL);
// if (tiling_flags & RADEON_TILING_MACRO)
// fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
 
// if (tiling_flags & RADEON_TILING_MICRO)
// fb_format |= AVIVO_D1GRPH_TILED;
if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= AVIVO_D1GRPH_TILED;
 
if (radeon_crtc->crtc_id == 0)
WREG32(AVIVO_D1VGA_CONTROL, 0);
/drivers/video/drm/radeon/cursor.S
0,0 → 1,13
 
.global _destroy_cursor
.global _fini_cursor
 
.section .text
 
_destroy_cursor:
pushl %eax
call _fini_cursor
addl $4, %esp
ret
 
 
/drivers/video/drm/radeon/r100.c
63,6 → 63,95
* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
*/
 
/* hpd for digital panel detect/disconnect */
bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
{
bool connected = false;
 
switch (hpd) {
case RADEON_HPD_1:
if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
connected = true;
break;
case RADEON_HPD_2:
if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
connected = true;
break;
default:
break;
}
return connected;
}
 
void r100_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd)
{
u32 tmp;
bool connected = r100_hpd_sense(rdev, hpd);
 
switch (hpd) {
case RADEON_HPD_1:
tmp = RREG32(RADEON_FP_GEN_CNTL);
if (connected)
tmp &= ~RADEON_FP_DETECT_INT_POL;
else
tmp |= RADEON_FP_DETECT_INT_POL;
WREG32(RADEON_FP_GEN_CNTL, tmp);
break;
case RADEON_HPD_2:
tmp = RREG32(RADEON_FP2_GEN_CNTL);
if (connected)
tmp &= ~RADEON_FP2_DETECT_INT_POL;
else
tmp |= RADEON_FP2_DETECT_INT_POL;
WREG32(RADEON_FP2_GEN_CNTL, tmp);
break;
default:
break;
}
}
 
void r100_hpd_init(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_connector *connector;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
rdev->irq.hpd[0] = true;
break;
case RADEON_HPD_2:
rdev->irq.hpd[1] = true;
break;
default:
break;
}
}
r100_irq_set(rdev);
}
 
void r100_hpd_fini(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_connector *connector;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
rdev->irq.hpd[0] = false;
break;
case RADEON_HPD_2:
rdev->irq.hpd[1] = false;
break;
default:
break;
}
}
}
 
/*
* PCI GART
*/
92,6 → 181,15
return radeon_gart_table_ram_alloc(rdev);
}
 
/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
void r100_enable_bm(struct radeon_device *rdev)
{
uint32_t tmp;
/* Enable bus mastering */
tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
WREG32(RADEON_BUS_CNTL, tmp);
}
 
int r100_pci_gart_enable(struct radeon_device *rdev)
{
uint32_t tmp;
103,9 → 201,6
WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
WREG32(RADEON_AIC_HI_ADDR, tmp);
/* Enable bus mastering */
tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
WREG32(RADEON_BUS_CNTL, tmp);
/* set PCI GART page-table base address */
WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
157,8 → 252,9
static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
{
uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
RADEON_CRTC2_VBLANK_STAT;
uint32_t irq_mask = RADEON_SW_INT_TEST |
RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
 
if (irqs) {
WREG32(RADEON_GEN_INT_STATUS, irqs);
192,24 → 288,27
int r;
 
if (rdev->wb.wb_obj == NULL) {
r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
true,
r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT,
false, &rdev->wb.wb_obj);
&rdev->wb.wb_obj);
if (r) {
DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
dev_err(rdev->dev, "(%d) create WB buffer failed\n", r);
return r;
}
r = radeon_object_pin(rdev->wb.wb_obj,
RADEON_GEM_DOMAIN_GTT,
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
&rdev->wb.gpu_addr);
if (r) {
DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r);
radeon_bo_unreserve(rdev->wb.wb_obj);
return r;
}
r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
radeon_bo_unreserve(rdev->wb.wb_obj);
if (r) {
DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
return r;
}
}
227,6 → 326,8
 
void r100_wb_fini(struct radeon_device *rdev)
{
int r;
 
r100_wb_disable(rdev);
if (rdev->wb.wb_obj) {
// radeon_object_kunmap(rdev->wb.wb_obj);
1245,17 → 1346,17
 
int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
struct radeon_object *robj)
struct radeon_bo *robj)
{
unsigned idx;
u32 value;
idx = pkt->idx + 1;
value = radeon_get_ib_value(p, idx + 2);
if ((value + 1) > radeon_object_size(robj)) {
if ((value + 1) > radeon_bo_size(robj)) {
DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
"(need %u have %lu) !\n",
value + 1,
radeon_object_size(robj));
radeon_bo_size(robj));
return -EINVAL;
}
return 0;
1541,6 → 1642,14
r100_hdp_reset(rdev);
}
 
void r100_hdp_flush(struct radeon_device *rdev)
{
u32 tmp;
tmp = RREG32(RADEON_HOST_PATH_CNTL);
tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE;
WREG32(RADEON_HOST_PATH_CNTL, tmp);
}
 
void r100_hdp_reset(struct radeon_device *rdev)
{
uint32_t tmp;
1612,6 → 1721,17
return 0;
}
 
void r100_set_common_regs(struct radeon_device *rdev)
{
/* set these so they don't interfere with anything */
WREG32(RADEON_OV0_SCALE_CNTL, 0);
WREG32(RADEON_SUBPIC_CNTL, 0);
WREG32(RADEON_VIPH_CONTROL, 0);
WREG32(RADEON_I2C_CNTL_1, 0);
WREG32(RADEON_DVI_I2C_CNTL_1, 0);
WREG32(RADEON_CAP0_TRIG_CNTL, 0);
WREG32(RADEON_CAP1_TRIG_CNTL, 0);
}
 
/*
* VRAM info
2677,6 → 2797,9
{
int r;
 
/* set common regs */
r100_set_common_regs(rdev);
/* program mc */
r100_mc_program(rdev);
/* Resume clock */
r100_clock_startup(rdev);
2684,6 → 2807,7
r100_gpu_init(rdev);
/* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */
r100_enable_bm(rdev);
if (rdev->flags & RADEON_IS_PCI) {
r = r100_pci_gart_enable(rdev);
if (r)
2690,7 → 2814,6
return r;
}
/* Enable IRQ */
// rdev->irq.sw_int = true;
// r100_irq_set(rdev);
/* 1M ring buffer */
// r = r100_cp_init(rdev, 1024 * 1024);
2772,10 → 2895,8
RREG32(R_0007C0_CP_STAT));
}
/* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
radeon_combios_asic_init(rdev->ddev);
}
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
/* Set asic errata */
r100_errata(rdev);
/* Initialize clocks */
2795,7 → 2916,7
// if (r)
// return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
if (rdev->flags & RADEON_IS_PCI) {
/drivers/video/drm/radeon/r300.c
137,7 → 137,8
 
void rv370_pcie_gart_disable(struct radeon_device *rdev)
{
uint32_t tmp;
u32 tmp;
int r;
 
tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
1192,6 → 1193,9
{
int r;
 
/* set common regs */
r100_set_common_regs(rdev);
/* program mc */
r300_mc_program(rdev);
/* Resume clock */
r300_clock_startup(rdev);
1204,6 → 1208,12
if (r)
return r;
}
 
if (rdev->family == CHIP_R300 ||
rdev->family == CHIP_R350 ||
rdev->family == CHIP_RV350)
r100_enable_bm(rdev);
 
if (rdev->flags & RADEON_IS_PCI) {
r = r100_pci_gart_enable(rdev);
if (r)
1210,7 → 1220,6
return r;
}
/* Enable IRQ */
// rdev->irq.sw_int = true;
// r100_irq_set(rdev);
/* 1M ring buffer */
// r = r100_cp_init(rdev, 1024 * 1024);
1265,10 → 1274,8
RREG32(R_0007C0_CP_STAT));
}
/* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
radeon_combios_asic_init(rdev->ddev);
}
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
/* Set asic errata */
r300_errata(rdev);
/* Initialize clocks */
/drivers/video/drm/radeon/r420.c
169,6 → 169,9
{
int r;
 
/* set common regs */
r100_set_common_regs(rdev);
/* program mc */
r300_mc_program(rdev);
/* Resume clock */
r420_clock_resume(rdev);
186,7 → 189,6
}
r420_pipes_init(rdev);
/* Enable IRQ */
// rdev->irq.sw_int = true;
// r100_irq_set(rdev);
/* 1M ring buffer */
// r = r100_cp_init(rdev, 1024 * 1024);
229,7 → 231,8
}
/* Resume clock after posting */
r420_clock_resume(rdev);
 
/* Initialize surface registers */
radeon_surface_init(rdev);
return r420_startup(rdev);
}
 
268,14 → 271,9
RREG32(R_0007C0_CP_STAT));
}
/* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
if (rdev->is_atom_bios) {
atom_asic_init(rdev->mode_info.atom_context);
} else {
radeon_combios_asic_init(rdev->ddev);
}
}
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
 
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
/* Initialize power management */
298,10 → 296,13
// return r;
// }
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r) {
return r;
}
if (rdev->family == CHIP_R420)
r100_enable_bm(rdev);
 
if (rdev->flags & RADEON_IS_PCIE) {
r = rv370_pcie_gart_init(rdev);
if (r)
/drivers/video/drm/radeon/r500_reg.h
716,6 → 716,8
 
#define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988
 
#define AVIVO_DC_GPIO_HPD_A 0x7e94
 
#define AVIVO_GPIO_0 0x7e30
#define AVIVO_GPIO_1 0x7e40
#define AVIVO_GPIO_2 0x7e50
/drivers/video/drm/radeon/r520.c
187,7 → 187,6
return r;
}
/* Enable IRQ */
// rdev->irq.sw_int = true;
// rs600_irq_set(rdev);
/* 1M ring buffer */
// r = r100_cp_init(rdev, 1024 * 1024);
240,6 → 239,9
RREG32(R_0007C0_CP_STAT));
}
/* check if cards are posted or not */
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
 
if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
atom_asic_init(rdev->mode_info.atom_context);
264,7 → 266,7
// if (r)
// return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
r = rv370_pcie_gart_init(rdev);
/drivers/video/drm/radeon/r600.c
37,8 → 37,10
 
#define PFP_UCODE_SIZE 576
#define PM4_UCODE_SIZE 1792
#define RLC_UCODE_SIZE 768
#define R700_PFP_UCODE_SIZE 848
#define R700_PM4_UCODE_SIZE 1360
#define R700_RLC_UCODE_SIZE 1024
 
/* Firmware Names */
MODULE_FIRMWARE("radeon/R600_pfp.bin");
61,6 → 63,8
MODULE_FIRMWARE("radeon/RV730_me.bin");
MODULE_FIRMWARE("radeon/RV710_pfp.bin");
MODULE_FIRMWARE("radeon/RV710_me.bin");
MODULE_FIRMWARE("radeon/R600_rlc.bin");
MODULE_FIRMWARE("radeon/R700_rlc.bin");
 
int r600_debugfs_mc_info_init(struct radeon_device *rdev);
 
69,6 → 73,281
void r600_gpu_init(struct radeon_device *rdev);
void r600_fini(struct radeon_device *rdev);
 
/* hpd for digital panel detect/disconnect */
bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
{
bool connected = false;
 
if (ASIC_IS_DCE3(rdev)) {
switch (hpd) {
case RADEON_HPD_1:
if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
connected = true;
break;
case RADEON_HPD_2:
if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
connected = true;
break;
case RADEON_HPD_3:
if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
connected = true;
break;
case RADEON_HPD_4:
if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
connected = true;
break;
/* DCE 3.2 */
case RADEON_HPD_5:
if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
connected = true;
break;
case RADEON_HPD_6:
if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
connected = true;
break;
default:
break;
}
} else {
switch (hpd) {
case RADEON_HPD_1:
if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
connected = true;
break;
case RADEON_HPD_2:
if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
connected = true;
break;
case RADEON_HPD_3:
if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
connected = true;
break;
default:
break;
}
}
return connected;
}
 
void r600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd)
{
u32 tmp;
bool connected = r600_hpd_sense(rdev, hpd);
 
if (ASIC_IS_DCE3(rdev)) {
switch (hpd) {
case RADEON_HPD_1:
tmp = RREG32(DC_HPD1_INT_CONTROL);
if (connected)
tmp &= ~DC_HPDx_INT_POLARITY;
else
tmp |= DC_HPDx_INT_POLARITY;
WREG32(DC_HPD1_INT_CONTROL, tmp);
break;
case RADEON_HPD_2:
tmp = RREG32(DC_HPD2_INT_CONTROL);
if (connected)
tmp &= ~DC_HPDx_INT_POLARITY;
else
tmp |= DC_HPDx_INT_POLARITY;
WREG32(DC_HPD2_INT_CONTROL, tmp);
break;
case RADEON_HPD_3:
tmp = RREG32(DC_HPD3_INT_CONTROL);
if (connected)
tmp &= ~DC_HPDx_INT_POLARITY;
else
tmp |= DC_HPDx_INT_POLARITY;
WREG32(DC_HPD3_INT_CONTROL, tmp);
break;
case RADEON_HPD_4:
tmp = RREG32(DC_HPD4_INT_CONTROL);
if (connected)
tmp &= ~DC_HPDx_INT_POLARITY;
else
tmp |= DC_HPDx_INT_POLARITY;
WREG32(DC_HPD4_INT_CONTROL, tmp);
break;
case RADEON_HPD_5:
tmp = RREG32(DC_HPD5_INT_CONTROL);
if (connected)
tmp &= ~DC_HPDx_INT_POLARITY;
else
tmp |= DC_HPDx_INT_POLARITY;
WREG32(DC_HPD5_INT_CONTROL, tmp);
break;
/* DCE 3.2 */
case RADEON_HPD_6:
tmp = RREG32(DC_HPD6_INT_CONTROL);
if (connected)
tmp &= ~DC_HPDx_INT_POLARITY;
else
tmp |= DC_HPDx_INT_POLARITY;
WREG32(DC_HPD6_INT_CONTROL, tmp);
break;
default:
break;
}
} else {
switch (hpd) {
case RADEON_HPD_1:
tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
if (connected)
tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
else
tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
break;
case RADEON_HPD_2:
tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
if (connected)
tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
else
tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
break;
case RADEON_HPD_3:
tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
if (connected)
tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
else
tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
break;
default:
break;
}
}
}
 
void r600_hpd_init(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_connector *connector;
 
if (ASIC_IS_DCE3(rdev)) {
u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
if (ASIC_IS_DCE32(rdev))
tmp |= DC_HPDx_EN;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(DC_HPD1_CONTROL, tmp);
rdev->irq.hpd[0] = true;
break;
case RADEON_HPD_2:
WREG32(DC_HPD2_CONTROL, tmp);
rdev->irq.hpd[1] = true;
break;
case RADEON_HPD_3:
WREG32(DC_HPD3_CONTROL, tmp);
rdev->irq.hpd[2] = true;
break;
case RADEON_HPD_4:
WREG32(DC_HPD4_CONTROL, tmp);
rdev->irq.hpd[3] = true;
break;
/* DCE 3.2 */
case RADEON_HPD_5:
WREG32(DC_HPD5_CONTROL, tmp);
rdev->irq.hpd[4] = true;
break;
case RADEON_HPD_6:
WREG32(DC_HPD6_CONTROL, tmp);
rdev->irq.hpd[5] = true;
break;
default:
break;
}
}
} else {
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
rdev->irq.hpd[0] = true;
break;
case RADEON_HPD_2:
WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
rdev->irq.hpd[1] = true;
break;
case RADEON_HPD_3:
WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
rdev->irq.hpd[2] = true;
break;
default:
break;
}
}
}
r600_irq_set(rdev);
}
 
void r600_hpd_fini(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_connector *connector;
 
if (ASIC_IS_DCE3(rdev)) {
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(DC_HPD1_CONTROL, 0);
rdev->irq.hpd[0] = false;
break;
case RADEON_HPD_2:
WREG32(DC_HPD2_CONTROL, 0);
rdev->irq.hpd[1] = false;
break;
case RADEON_HPD_3:
WREG32(DC_HPD3_CONTROL, 0);
rdev->irq.hpd[2] = false;
break;
case RADEON_HPD_4:
WREG32(DC_HPD4_CONTROL, 0);
rdev->irq.hpd[3] = false;
break;
/* DCE 3.2 */
case RADEON_HPD_5:
WREG32(DC_HPD5_CONTROL, 0);
rdev->irq.hpd[4] = false;
break;
case RADEON_HPD_6:
WREG32(DC_HPD6_CONTROL, 0);
rdev->irq.hpd[5] = false;
break;
default:
break;
}
}
} else {
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
rdev->irq.hpd[0] = false;
break;
case RADEON_HPD_2:
WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
rdev->irq.hpd[1] = false;
break;
case RADEON_HPD_3:
WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
rdev->irq.hpd[2] = false;
break;
default:
break;
}
}
}
}
 
/*
* R600 PCIE GART
*/
179,7 → 458,7
void r600_pcie_gart_disable(struct radeon_device *rdev)
{
u32 tmp;
int i;
int i, r;
 
/* Disable all tables */
for (i = 0; i < 7; i++)
1100,6 → 1379,10
(void)RREG32(PCIE_PORT_DATA);
}
 
void r600_hdp_flush(struct radeon_device *rdev)
{
WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
}
 
/*
* CP & Ring
1285,7 → 1568,11
if (r)
return r;
/* Post card if necessary */
if (!r600_card_posted(rdev) && rdev->bios) {
if (!r600_card_posted(rdev)) {
if (!rdev->bios) {
dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
return -EINVAL;
}
DRM_INFO("GPU not posted. posting now...\n");
atom_asic_init(rdev->mode_info.atom_context);
}
1309,25 → 1596,24
if (r)
return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
 
// r = radeon_irq_kms_init(rdev);
// if (r)
// return r;
 
// rdev->cp.ring_obj = NULL;
// r600_ring_init(rdev, 1024 * 1024);
 
// if (!rdev->me_fw || !rdev->pfp_fw) {
// r = r600_cp_init_microcode(rdev);
// if (r) {
// DRM_ERROR("Failed to load firmware!\n");
// return r;
// }
// }
// rdev->ih.ring_obj = NULL;
// r600_ih_ring_init(rdev, 64 * 1024);
 
r = r600_pcie_gart_init(rdev);
if (r)
return r;
 
rdev->accel_working = true;
// r = r600_blit_init(rdev);
// if (r) {
// DRM_ERROR("radeon: failled blitter (%d).\n", r);
1334,6 → 1620,7
// return r;
// }
 
rdev->accel_working = true;
r = r600_startup(rdev);
if (r) {
// r600_suspend(rdev);
1375,21 → 1662,21
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private;
uint32_t rdp, wdp;
unsigned count, i, j;
 
radeon_ring_free_size(rdev);
rdp = RREG32(CP_RB_RPTR);
wdp = RREG32(CP_RB_WPTR);
count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw;
seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR));
seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR));
seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr);
seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr);
seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
seq_printf(m, "%u dwords in ring\n", count);
i = rdev->cp.rptr;
for (j = 0; j <= count; j++) {
i = (rdp + j) & rdev->cp.ptr_mask;
seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
i = (i + 1) & rdev->cp.ptr_mask;
}
return 0;
}
/drivers/video/drm/radeon/r600d.h
456,8 → 456,216
#define WAIT_2D_IDLECLEAN_bit (1 << 16)
#define WAIT_3D_IDLECLEAN_bit (1 << 17)
 
#define IH_RB_CNTL 0x3e00
# define IH_RB_ENABLE (1 << 0)
# define IH_IB_SIZE(x) ((x) << 1) /* log2 */
# define IH_RB_FULL_DRAIN_ENABLE (1 << 6)
# define IH_WPTR_WRITEBACK_ENABLE (1 << 8)
# define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */
# define IH_WPTR_OVERFLOW_ENABLE (1 << 16)
# define IH_WPTR_OVERFLOW_CLEAR (1 << 31)
#define IH_RB_BASE 0x3e04
#define IH_RB_RPTR 0x3e08
#define IH_RB_WPTR 0x3e0c
# define RB_OVERFLOW (1 << 0)
# define WPTR_OFFSET_MASK 0x3fffc
#define IH_RB_WPTR_ADDR_HI 0x3e10
#define IH_RB_WPTR_ADDR_LO 0x3e14
#define IH_CNTL 0x3e18
# define ENABLE_INTR (1 << 0)
# define IH_MC_SWAP(x) ((x) << 2)
# define IH_MC_SWAP_NONE 0
# define IH_MC_SWAP_16BIT 1
# define IH_MC_SWAP_32BIT 2
# define IH_MC_SWAP_64BIT 3
# define RPTR_REARM (1 << 4)
# define MC_WRREQ_CREDIT(x) ((x) << 15)
# define MC_WR_CLEAN_CNT(x) ((x) << 20)
 
#define RLC_CNTL 0x3f00
# define RLC_ENABLE (1 << 0)
#define RLC_HB_BASE 0x3f10
#define RLC_HB_CNTL 0x3f0c
#define RLC_HB_RPTR 0x3f20
#define RLC_HB_WPTR 0x3f1c
#define RLC_HB_WPTR_LSB_ADDR 0x3f14
#define RLC_HB_WPTR_MSB_ADDR 0x3f18
#define RLC_MC_CNTL 0x3f44
#define RLC_UCODE_CNTL 0x3f48
#define RLC_UCODE_ADDR 0x3f2c
#define RLC_UCODE_DATA 0x3f30
 
#define SRBM_SOFT_RESET 0xe60
# define SOFT_RESET_RLC (1 << 13)
 
#define CP_INT_CNTL 0xc124
# define CNTX_BUSY_INT_ENABLE (1 << 19)
# define CNTX_EMPTY_INT_ENABLE (1 << 20)
# define SCRATCH_INT_ENABLE (1 << 25)
# define TIME_STAMP_INT_ENABLE (1 << 26)
# define IB2_INT_ENABLE (1 << 29)
# define IB1_INT_ENABLE (1 << 30)
# define RB_INT_ENABLE (1 << 31)
#define CP_INT_STATUS 0xc128
# define SCRATCH_INT_STAT (1 << 25)
# define TIME_STAMP_INT_STAT (1 << 26)
# define IB2_INT_STAT (1 << 29)
# define IB1_INT_STAT (1 << 30)
# define RB_INT_STAT (1 << 31)
 
#define GRBM_INT_CNTL 0x8060
# define RDERR_INT_ENABLE (1 << 0)
# define WAIT_COUNT_TIMEOUT_INT_ENABLE (1 << 1)
# define GUI_IDLE_INT_ENABLE (1 << 19)
 
#define INTERRUPT_CNTL 0x5468
# define IH_DUMMY_RD_OVERRIDE (1 << 0)
# define IH_DUMMY_RD_EN (1 << 1)
# define IH_REQ_NONSNOOP_EN (1 << 3)
# define GEN_IH_INT_EN (1 << 8)
#define INTERRUPT_CNTL2 0x546c
 
#define D1MODE_VBLANK_STATUS 0x6534
#define D2MODE_VBLANK_STATUS 0x6d34
# define DxMODE_VBLANK_OCCURRED (1 << 0)
# define DxMODE_VBLANK_ACK (1 << 4)
# define DxMODE_VBLANK_STAT (1 << 12)
# define DxMODE_VBLANK_INTERRUPT (1 << 16)
# define DxMODE_VBLANK_INTERRUPT_TYPE (1 << 17)
#define D1MODE_VLINE_STATUS 0x653c
#define D2MODE_VLINE_STATUS 0x6d3c
# define DxMODE_VLINE_OCCURRED (1 << 0)
# define DxMODE_VLINE_ACK (1 << 4)
# define DxMODE_VLINE_STAT (1 << 12)
# define DxMODE_VLINE_INTERRUPT (1 << 16)
# define DxMODE_VLINE_INTERRUPT_TYPE (1 << 17)
#define DxMODE_INT_MASK 0x6540
# define D1MODE_VBLANK_INT_MASK (1 << 0)
# define D1MODE_VLINE_INT_MASK (1 << 4)
# define D2MODE_VBLANK_INT_MASK (1 << 8)
# define D2MODE_VLINE_INT_MASK (1 << 12)
#define DCE3_DISP_INTERRUPT_STATUS 0x7ddc
# define DC_HPD1_INTERRUPT (1 << 18)
# define DC_HPD2_INTERRUPT (1 << 19)
#define DISP_INTERRUPT_STATUS 0x7edc
# define LB_D1_VLINE_INTERRUPT (1 << 2)
# define LB_D2_VLINE_INTERRUPT (1 << 3)
# define LB_D1_VBLANK_INTERRUPT (1 << 4)
# define LB_D2_VBLANK_INTERRUPT (1 << 5)
# define DACA_AUTODETECT_INTERRUPT (1 << 16)
# define DACB_AUTODETECT_INTERRUPT (1 << 17)
# define DC_HOT_PLUG_DETECT1_INTERRUPT (1 << 18)
# define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19)
# define DC_I2C_SW_DONE_INTERRUPT (1 << 20)
# define DC_I2C_HW_DONE_INTERRUPT (1 << 21)
#define DISP_INTERRUPT_STATUS_CONTINUE 0x7ee8
#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8
# define DC_HPD4_INTERRUPT (1 << 14)
# define DC_HPD4_RX_INTERRUPT (1 << 15)
# define DC_HPD3_INTERRUPT (1 << 28)
# define DC_HPD1_RX_INTERRUPT (1 << 29)
# define DC_HPD2_RX_INTERRUPT (1 << 30)
#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2 0x7dec
# define DC_HPD3_RX_INTERRUPT (1 << 0)
# define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 1)
# define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 2)
# define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 3)
# define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 4)
# define AUX1_SW_DONE_INTERRUPT (1 << 5)
# define AUX1_LS_DONE_INTERRUPT (1 << 6)
# define AUX2_SW_DONE_INTERRUPT (1 << 7)
# define AUX2_LS_DONE_INTERRUPT (1 << 8)
# define AUX3_SW_DONE_INTERRUPT (1 << 9)
# define AUX3_LS_DONE_INTERRUPT (1 << 10)
# define AUX4_SW_DONE_INTERRUPT (1 << 11)
# define AUX4_LS_DONE_INTERRUPT (1 << 12)
# define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 13)
# define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 14)
/* DCE 3.2 */
# define AUX5_SW_DONE_INTERRUPT (1 << 15)
# define AUX5_LS_DONE_INTERRUPT (1 << 16)
# define AUX6_SW_DONE_INTERRUPT (1 << 17)
# define AUX6_LS_DONE_INTERRUPT (1 << 18)
# define DC_HPD5_INTERRUPT (1 << 19)
# define DC_HPD5_RX_INTERRUPT (1 << 20)
# define DC_HPD6_INTERRUPT (1 << 21)
# define DC_HPD6_RX_INTERRUPT (1 << 22)
 
#define DACA_AUTO_DETECT_CONTROL 0x7828
#define DACB_AUTO_DETECT_CONTROL 0x7a28
#define DCE3_DACA_AUTO_DETECT_CONTROL 0x7028
#define DCE3_DACB_AUTO_DETECT_CONTROL 0x7128
# define DACx_AUTODETECT_MODE(x) ((x) << 0)
# define DACx_AUTODETECT_MODE_NONE 0
# define DACx_AUTODETECT_MODE_CONNECT 1
# define DACx_AUTODETECT_MODE_DISCONNECT 2
# define DACx_AUTODETECT_FRAME_TIME_COUNTER(x) ((x) << 8)
/* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */
# define DACx_AUTODETECT_CHECK_MASK(x) ((x) << 16)
 
#define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038
#define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138
#define DACA_AUTODETECT_INT_CONTROL 0x7838
#define DACB_AUTODETECT_INT_CONTROL 0x7a38
# define DACx_AUTODETECT_ACK (1 << 0)
# define DACx_AUTODETECT_INT_ENABLE (1 << 16)
 
#define DC_HOT_PLUG_DETECT1_CONTROL 0x7d00
#define DC_HOT_PLUG_DETECT2_CONTROL 0x7d10
#define DC_HOT_PLUG_DETECT3_CONTROL 0x7d24
# define DC_HOT_PLUG_DETECTx_EN (1 << 0)
 
#define DC_HOT_PLUG_DETECT1_INT_STATUS 0x7d04
#define DC_HOT_PLUG_DETECT2_INT_STATUS 0x7d14
#define DC_HOT_PLUG_DETECT3_INT_STATUS 0x7d28
# define DC_HOT_PLUG_DETECTx_INT_STATUS (1 << 0)
# define DC_HOT_PLUG_DETECTx_SENSE (1 << 1)
 
/* DCE 3.0 */
#define DC_HPD1_INT_STATUS 0x7d00
#define DC_HPD2_INT_STATUS 0x7d0c
#define DC_HPD3_INT_STATUS 0x7d18
#define DC_HPD4_INT_STATUS 0x7d24
/* DCE 3.2 */
#define DC_HPD5_INT_STATUS 0x7dc0
#define DC_HPD6_INT_STATUS 0x7df4
# define DC_HPDx_INT_STATUS (1 << 0)
# define DC_HPDx_SENSE (1 << 1)
# define DC_HPDx_RX_INT_STATUS (1 << 8)
 
#define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08
#define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18
#define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c
# define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0)
# define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8)
# define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16)
/* DCE 3.0 */
#define DC_HPD1_INT_CONTROL 0x7d04
#define DC_HPD2_INT_CONTROL 0x7d10
#define DC_HPD3_INT_CONTROL 0x7d1c
#define DC_HPD4_INT_CONTROL 0x7d28
/* DCE 3.2 */
#define DC_HPD5_INT_CONTROL 0x7dc4
#define DC_HPD6_INT_CONTROL 0x7df8
# define DC_HPDx_INT_ACK (1 << 0)
# define DC_HPDx_INT_POLARITY (1 << 8)
# define DC_HPDx_INT_EN (1 << 16)
# define DC_HPDx_RX_INT_ACK (1 << 20)
# define DC_HPDx_RX_INT_EN (1 << 24)
 
/* DCE 3.0 */
#define DC_HPD1_CONTROL 0x7d08
#define DC_HPD2_CONTROL 0x7d14
#define DC_HPD3_CONTROL 0x7d20
#define DC_HPD4_CONTROL 0x7d2c
/* DCE 3.2 */
#define DC_HPD5_CONTROL 0x7dc8
#define DC_HPD6_CONTROL 0x7dfc
# define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0)
# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16)
/* DCE 3.2 */
# define DC_HPDx_EN (1 << 28)
 
/*
* PM4
*/
500,7 → 708,6
#define PACKET3_WAIT_REG_MEM 0x3C
#define PACKET3_MEM_WRITE 0x3D
#define PACKET3_INDIRECT_BUFFER 0x32
#define PACKET3_CP_INTERRUPT 0x40
#define PACKET3_SURFACE_SYNC 0x43
# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
# define PACKET3_TC_ACTION_ENA (1 << 23)
674,4 → 881,5
#define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16)
#define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17)
 
#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480
#endif
/drivers/video/drm/radeon/radeon.h
28,8 → 28,6
#ifndef __RADEON_H__
#define __RADEON_H__
 
//#include "radeon_object.h"
 
/* TODO: Here are things that needs to be done :
* - surface allocator & initializer : (bit like scratch reg) should
* initialize HDP_ stuff on RS600, R600, R700 hw, well anythings
62,11 → 60,16
* are considered as fatal)
*/
 
#include <asm/atomic.h>
 
#include <types.h>
#include <linux/list.h>
#include <linux/kref.h>
 
#include <ttm/ttm_bo_api.h>
#include <ttm/ttm_bo_driver.h>
#include <ttm/ttm_placement.h>
#include <ttm/ttm_module.h>
 
#include <linux/list.h>
 
#include <pci.h>
 
93,7 → 96,9
extern int radeon_testing;
extern int radeon_connector_table;
extern int radeon_tv;
extern int radeon_new_pll;
 
 
typedef struct
{
int width;
100,7 → 105,7
int height;
int bpp;
int freq;
}mode_t;
}videomode_t;
 
static inline uint8_t __raw_readb(const volatile void __iomem *addr)
{
212,11 → 217,11
*/
struct radeon_fence_driver {
uint32_t scratch_reg;
// atomic_t seq;
atomic_t seq;
uint32_t last_seq;
unsigned long count_timeout;
// wait_queue_head_t queue;
// rwlock_t lock;
rwlock_t lock;
struct list_head created;
struct list_head emited;
struct list_head signaled;
224,7 → 229,7
 
struct radeon_fence {
struct radeon_device *rdev;
// struct kref kref;
struct kref kref;
struct list_head list;
/* protected by radeon_fence.lock */
uint32_t seq;
249,36 → 254,48
* Tiling registers
*/
struct radeon_surface_reg {
struct radeon_object *robj;
struct radeon_bo *bo;
};
 
#define RADEON_GEM_MAX_SURFACES 8
 
/*
* Radeon buffer.
* TTM.
*/
struct radeon_object;
struct radeon_mman {
struct ttm_bo_global_ref bo_global_ref;
struct ttm_global_reference mem_global_ref;
bool mem_global_referenced;
struct ttm_bo_device bdev;
};
 
struct radeon_object_list {
struct radeon_bo {
/* Protected by gem.mutex */
struct list_head list;
struct radeon_object *robj;
/* Protected by tbo.reserved */
u32 placements[3];
struct ttm_placement placement;
struct ttm_buffer_object tbo;
struct ttm_bo_kmap_obj kmap;
unsigned pin_count;
void *kptr;
u32 tiling_flags;
u32 pitch;
int surface_reg;
/* Constant after initialization */
struct radeon_device *rdev;
struct drm_gem_object *gobj;
};
 
struct radeon_bo_list {
struct list_head list;
struct radeon_bo *bo;
uint64_t gpu_offset;
unsigned rdomain;
unsigned wdomain;
uint32_t tiling_flags;
u32 tiling_flags;
};
 
int radeon_object_init(struct radeon_device *rdev);
void radeon_object_fini(struct radeon_device *rdev);
int radeon_object_create(struct radeon_device *rdev,
struct drm_gem_object *gobj,
unsigned long size,
bool kernel,
uint32_t domain,
bool interruptible,
struct radeon_object **robj_ptr);
 
 
/*
* GEM objects.
*/
291,7 → 308,6
int radeon_gem_object_create(struct radeon_device *rdev, int size,
int alignment, int initial_domain,
bool discardable, bool kernel,
bool interruptible,
struct drm_gem_object **obj);
int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
uint64_t *gpu_addr);
308,7 → 324,7
};
 
struct radeon_gart_table_vram {
struct radeon_object *robj;
struct radeon_bo *robj;
volatile uint32_t *ptr;
};
 
389,12 → 405,17
bool sw_int;
/* FIXME: use a define max crtc rather than hardcode it */
bool crtc_vblank_int[2];
/* FIXME: use defines for max hpd/dacs */
bool hpd[6];
spinlock_t sw_lock;
int sw_refcount;
};
 
int radeon_irq_kms_init(struct radeon_device *rdev);
void radeon_irq_kms_fini(struct radeon_device *rdev);
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev);
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
 
 
/*
* CP & ring.
*/
413,7 → 434,7
*/
struct radeon_ib_pool {
// struct mutex mutex;
struct radeon_object *robj;
struct radeon_bo *robj;
struct list_head scheduled_ibs;
struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
bool ready;
421,7 → 442,7
};
 
struct radeon_cp {
struct radeon_object *ring_obj;
struct radeon_bo *ring_obj;
volatile uint32_t *ring;
unsigned rptr;
unsigned wptr;
436,8 → 457,25
bool ready;
};
 
/*
* R6xx+ IH ring
*/
struct r600_ih {
struct radeon_bo *ring_obj;
volatile uint32_t *ring;
unsigned rptr;
unsigned wptr;
unsigned wptr_old;
unsigned ring_size;
uint64_t gpu_addr;
uint32_t align_mask;
uint32_t ptr_mask;
spinlock_t lock;
bool enabled;
};
 
struct r600_blit {
struct radeon_object *shader_obj;
struct radeon_bo *shader_obj;
u64 shader_gpu_addr;
u32 vs_offset, ps_offset;
u32 state_offset;
467,8 → 505,8
*/
struct radeon_cs_reloc {
// struct drm_gem_object *gobj;
struct radeon_object *robj;
struct radeon_object_list lobj;
struct radeon_bo *robj;
// struct radeon_bo_list lobj;
uint32_t handle;
uint32_t flags;
};
556,6 → 594,7
* AGP
*/
int radeon_agp_init(struct radeon_device *rdev);
void radeon_agp_resume(struct radeon_device *rdev);
void radeon_agp_fini(struct radeon_device *rdev);
 
 
563,7 → 602,7
* Writeback
*/
struct radeon_wb {
struct radeon_object *wb_obj;
struct radeon_bo *wb_obj;
volatile uint32_t *wb;
uint64_t gpu_addr;
};
651,6 → 690,11
uint32_t offset, uint32_t obj_size);
int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
void (*bandwidth_update)(struct radeon_device *rdev);
void (*hdp_flush)(struct radeon_device *rdev);
void (*hpd_init)(struct radeon_device *rdev);
void (*hpd_fini)(struct radeon_device *rdev);
bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
};
 
/*
738,10 → 782,9
uint8_t *bios;
bool is_atom_bios;
uint16_t bios_header_start;
 
// struct radeon_object *stollen_vga_memory;
struct radeon_bo *stollen_vga_memory;
struct fb_info *fbdev_info;
struct radeon_object *fbdev_robj;
struct radeon_bo *fbdev_rbo;
struct radeon_framebuffer *fbdev_rfb;
/* Register mmio */
unsigned long rmmio_base;
759,7 → 802,7
struct radeon_gart gart;
struct radeon_mode_info mode_info;
struct radeon_scratch scratch;
// struct radeon_mman mman;
struct radeon_mman mman;
struct radeon_fence_driver fence_drv;
struct radeon_cp cp;
struct radeon_ib_pool ib_pool;
817,6 → 860,10
}
}
 
/*
* Cast helper
*/
#define to_radeon_fence(p) ((struct radeon_fence *)(p))
 
/*
* Registers read & write functions.
951,12 → 998,17
#define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
#define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
#define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e))
#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
#define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
#define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
#define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev))
#define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev))
#define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev))
#define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd))
#define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd))
 
/* Common functions */
extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
963,6 → 1015,7
extern int radeon_modeset_init(struct radeon_device *rdev);
extern void radeon_modeset_fini(struct radeon_device *rdev);
extern bool radeon_card_posted(struct radeon_device *rdev);
extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
extern int radeon_clocks_init(struct radeon_device *rdev);
extern void radeon_clocks_fini(struct radeon_device *rdev);
extern void radeon_scratch_init(struct radeon_device *rdev);
970,6 → 1023,7
extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
 
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
struct r100_mc_save {
1007,7 → 1061,7
extern void r100_vga_render_disable(struct radeon_device *rdev);
extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
struct radeon_object *robj);
struct radeon_bo *robj);
extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
const unsigned *auth, unsigned n,
1015,6 → 1069,8
extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx);
extern void r100_enable_bm(struct radeon_device *rdev);
extern void r100_set_common_regs(struct radeon_device *rdev);
 
/* rv200,rv250,rv280 */
extern void r200_set_safe_registers(struct radeon_device *rdev);
1090,11 → 1146,16
extern void r600_scratch_init(struct radeon_device *rdev);
extern int r600_blit_init(struct radeon_device *rdev);
extern void r600_blit_fini(struct radeon_device *rdev);
extern int r600_cp_init_microcode(struct radeon_device *rdev);
extern int r600_init_microcode(struct radeon_device *rdev);
extern int r600_gpu_reset(struct radeon_device *rdev);
/* r600 irq */
extern int r600_irq_init(struct radeon_device *rdev);
extern void r600_irq_fini(struct radeon_device *rdev);
extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
extern int r600_irq_set(struct radeon_device *rdev);
 
#include "radeon_object.h"
 
 
#define DRM_UDELAY(d) udelay(d)
 
resource_size_t
/drivers/video/drm/radeon/radeon_asic.h
76,6 → 76,12
void r100_bandwidth_update(struct radeon_device *rdev);
void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int r100_ring_test(struct radeon_device *rdev);
void r100_hdp_flush(struct radeon_device *rdev);
void r100_hpd_init(struct radeon_device *rdev);
void r100_hpd_fini(struct radeon_device *rdev);
bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void r100_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
 
static struct radeon_asic r100_asic = {
.init = &r100_init,
107,6 → 113,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &r100_hpd_init,
.hpd_fini = &r100_hpd_fini,
.hpd_sense = &r100_hpd_sense,
.hpd_set_polarity = &r100_hpd_set_polarity,
};
 
 
162,6 → 173,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &r100_hpd_init,
.hpd_fini = &r100_hpd_fini,
.hpd_sense = &r100_hpd_sense,
.hpd_set_polarity = &r100_hpd_set_polarity,
};
 
/*
201,6 → 217,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &r100_hpd_init,
.hpd_fini = &r100_hpd_fini,
.hpd_sense = &r100_hpd_sense,
.hpd_set_polarity = &r100_hpd_set_polarity,
};
 
 
245,6 → 266,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &r100_hpd_init,
.hpd_fini = &r100_hpd_fini,
.hpd_sense = &r100_hpd_sense,
.hpd_set_polarity = &r100_hpd_set_polarity,
};
 
 
263,6 → 289,12
uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void rs600_bandwidth_update(struct radeon_device *rdev);
void rs600_hpd_init(struct radeon_device *rdev);
void rs600_hpd_fini(struct radeon_device *rdev);
bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void rs600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
 
static struct radeon_asic rs600_asic = {
.init = &rs600_init,
// .fini = &rs600_fini,
291,6 → 323,11
.set_pcie_lanes = NULL,
.set_clock_gating = &radeon_atom_set_clock_gating,
.bandwidth_update = &rs600_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &rs600_hpd_init,
.hpd_fini = &rs600_hpd_fini,
.hpd_sense = &rs600_hpd_sense,
.hpd_set_polarity = &rs600_hpd_set_polarity,
};
 
 
334,6 → 371,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &rs690_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &rs600_hpd_init,
.hpd_fini = &rs600_hpd_fini,
.hpd_sense = &rs600_hpd_sense,
.hpd_set_polarity = &rs600_hpd_set_polarity,
};
 
 
381,6 → 423,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &rs600_hpd_init,
.hpd_fini = &rs600_hpd_fini,
.hpd_sense = &rs600_hpd_sense,
.hpd_set_polarity = &rs600_hpd_set_polarity,
};
 
 
419,6 → 466,11
.set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
.hpd_init = &rs600_hpd_init,
.hpd_fini = &rs600_hpd_fini,
.hpd_sense = &rs600_hpd_sense,
.hpd_set_polarity = &rs600_hpd_set_polarity,
};
 
/*
455,6 → 507,12
int r600_copy_blit(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_pages, struct radeon_fence *fence);
void r600_hdp_flush(struct radeon_device *rdev);
void r600_hpd_init(struct radeon_device *rdev);
void r600_hpd_fini(struct radeon_device *rdev);
bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void r600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
 
static struct radeon_asic r600_asic = {
.init = &r600_init,
484,6 → 542,11
.set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r600_hdp_flush,
.hpd_init = &r600_hpd_init,
.hpd_fini = &r600_hpd_fini,
.hpd_sense = &r600_hpd_sense,
.hpd_set_polarity = &r600_hpd_set_polarity,
};
 
/*
523,6 → 586,11
.set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r600_hdp_flush,
.hpd_init = &r600_hpd_init,
.hpd_fini = &r600_hpd_fini,
.hpd_sense = &r600_hpd_sense,
.hpd_set_polarity = &r600_hpd_set_polarity,
};
 
#endif
/drivers/video/drm/radeon/radeon_atombios.c
47,7 → 47,8
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
bool linkb, uint32_t igp_lane_info,
uint16_t connector_object_id);
uint16_t connector_object_id,
struct radeon_hpd *hpd);
 
/* from radeon_legacy_encoder.c */
extern void
60,16 → 61,16
struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
};
 
static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device
*dev, uint8_t id)
static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
uint8_t id)
{
struct radeon_device *rdev = dev->dev_private;
struct atom_context *ctx = rdev->mode_info.atom_context;
ATOM_GPIO_I2C_ASSIGMENT gpio;
ATOM_GPIO_I2C_ASSIGMENT *gpio;
struct radeon_i2c_bus_rec i2c;
int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
struct _ATOM_GPIO_I2C_INFO *i2c_info;
uint16_t data_offset;
int i;
 
memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
i2c.valid = false;
78,34 → 79,121
 
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
gpio = i2c_info->asGPIO_Info[id];
 
i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
i2c.put_data_mask = (1 << gpio.ucDataEnShift);
i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
i2c.get_data_mask = (1 << gpio.ucDataY_Shift);
i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
gpio = &i2c_info->asGPIO_Info[i];
 
if (gpio->sucI2cId.ucAccess == id) {
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
i2c.en_data_mask = (1 << gpio->ucDataEnShift);
i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
 
if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
i2c.hw_capable = true;
else
i2c.hw_capable = false;
 
if (gpio->sucI2cId.ucAccess == 0xa0)
i2c.mm_i2c = true;
else
i2c.mm_i2c = false;
 
i2c.i2c_id = gpio->sucI2cId.ucAccess;
 
i2c.valid = true;
}
}
 
return i2c;
}
 
static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
u8 id)
{
struct atom_context *ctx = rdev->mode_info.atom_context;
struct radeon_gpio_rec gpio;
int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
struct _ATOM_GPIO_PIN_LUT *gpio_info;
ATOM_GPIO_PIN_ASSIGNMENT *pin;
u16 data_offset, size;
int i, num_indices;
 
memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
gpio.valid = false;
 
atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
 
gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
 
num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
 
for (i = 0; i < num_indices; i++) {
pin = &gpio_info->asGPIO_Pin[i];
if (id == pin->ucGPIO_ID) {
gpio.id = pin->ucGPIO_ID;
gpio.reg = pin->usGpioPin_AIndex * 4;
gpio.mask = (1 << pin->ucGpioPinBitShift);
gpio.valid = true;
break;
}
}
 
return gpio;
}
 
static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,
struct radeon_gpio_rec *gpio)
{
struct radeon_hpd hpd;
hpd.gpio = *gpio;
if (gpio->reg == AVIVO_DC_GPIO_HPD_A) {
switch(gpio->mask) {
case (1 << 0):
hpd.hpd = RADEON_HPD_1;
break;
case (1 << 8):
hpd.hpd = RADEON_HPD_2;
break;
case (1 << 16):
hpd.hpd = RADEON_HPD_3;
break;
case (1 << 24):
hpd.hpd = RADEON_HPD_4;
break;
case (1 << 26):
hpd.hpd = RADEON_HPD_5;
break;
case (1 << 28):
hpd.hpd = RADEON_HPD_6;
break;
default:
hpd.hpd = RADEON_HPD_NONE;
break;
}
} else
hpd.hpd = RADEON_HPD_NONE;
return hpd;
}
 
static bool radeon_atom_apply_quirks(struct drm_device *dev,
uint32_t supported_device,
int *connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
uint16_t *line_mux)
uint16_t *line_mux,
struct radeon_hpd *hpd)
{
 
/* Asus M2A-VM HDMI board lists the DVI port as HDMI */
135,6 → 223,23
}
}
 
/* HIS X1300 is DVI+VGA, not DVI+DVI */
if ((dev->pdev->device == 0x7146) &&
(dev->pdev->subsystem_vendor == 0x17af) &&
(dev->pdev->subsystem_device == 0x2058)) {
if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
return false;
}
 
/* Gigabyte X1300 is DVI+VGA, not DVI+DVI */
if ((dev->pdev->device == 0x7142) &&
(dev->pdev->subsystem_vendor == 0x1458) &&
(dev->pdev->subsystem_device == 0x2134)) {
if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
return false;
}
 
 
/* Funky macbooks */
if ((dev->pdev->device == 0x71C5) &&
(dev->pdev->subsystem_vendor == 0x106b) &&
172,6 → 277,15
}
}
 
/* Acer laptop reports DVI-D as DVI-I */
if ((dev->pdev->device == 0x95c4) &&
(dev->pdev->subsystem_vendor == 0x1025) &&
(dev->pdev->subsystem_device == 0x013c)) {
if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&
(supported_device == ATOM_DEVICE_DFP1_SUPPORT))
*connector_type = DRM_MODE_CONNECTOR_DVID;
}
 
return true;
}
 
240,16 → 354,18
struct radeon_mode_info *mode_info = &rdev->mode_info;
struct atom_context *ctx = mode_info->atom_context;
int index = GetIndexIntoMasterTable(DATA, Object_Header);
uint16_t size, data_offset;
uint8_t frev, crev, line_mux = 0;
u16 size, data_offset;
u8 frev, crev;
ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
ATOM_OBJECT_HEADER *obj_header;
int i, j, path_size, device_support;
int connector_type;
uint16_t igp_lane_info, conn_id, connector_object_id;
u16 igp_lane_info, conn_id, connector_object_id;
bool linkb;
struct radeon_i2c_bus_rec ddc_bus;
struct radeon_gpio_rec gpio;
struct radeon_hpd hpd;
 
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
 
276,7 → 392,6
path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
path_size += le16_to_cpu(path->usSize);
linkb = false;
 
if (device_support & le16_to_cpu(path->usDeviceTag)) {
uint8_t con_obj_id, con_obj_num, con_obj_type;
 
377,10 → 492,9
}
}
 
/* look up gpio for ddc */
/* look up gpio for ddc, hpd */
if ((le16_to_cpu(path->usDeviceTag) &
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
== 0) {
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
if (le16_to_cpu(path->usConnObjectId) ==
le16_to_cpu(con_obj->asObjects[j].
394,22 → 508,35
asObjects[j].
usRecordOffset));
ATOM_I2C_RECORD *i2c_record;
ATOM_HPD_INT_RECORD *hpd_record;
ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
hpd.hpd = RADEON_HPD_NONE;
 
while (record->ucRecordType > 0
&& record->
ucRecordType <=
ATOM_MAX_OBJECT_RECORD_NUMBER) {
switch (record->
ucRecordType) {
switch (record->ucRecordType) {
case ATOM_I2C_RECORD_TYPE:
i2c_record =
(ATOM_I2C_RECORD
*) record;
line_mux =
i2c_record->
sucI2cId.
bfI2C_LineMux;
(ATOM_I2C_RECORD *)
record;
i2c_config =
(ATOM_I2C_ID_CONFIG_ACCESS *)
&i2c_record->sucI2cId;
ddc_bus = radeon_lookup_i2c_gpio(rdev,
i2c_config->
ucAccess);
break;
case ATOM_HPD_INT_RECORD_TYPE:
hpd_record =
(ATOM_HPD_INT_RECORD *)
record;
gpio = radeon_lookup_gpio(rdev,
hpd_record->ucHPDIntGPIOID);
hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
hpd.plugged_state = hpd_record->ucPlugged_PinState;
break;
}
record =
(ATOM_COMMON_RECORD_HEADER
421,24 → 548,16
break;
}
}
} else
line_mux = 0;
 
if ((le16_to_cpu(path->usDeviceTag) ==
ATOM_DEVICE_TV1_SUPPORT)
|| (le16_to_cpu(path->usDeviceTag) ==
ATOM_DEVICE_TV2_SUPPORT)
|| (le16_to_cpu(path->usDeviceTag) ==
ATOM_DEVICE_CV_SUPPORT))
} else {
hpd.hpd = RADEON_HPD_NONE;
ddc_bus.valid = false;
else
ddc_bus = radeon_lookup_gpio(dev, line_mux);
}
 
conn_id = le16_to_cpu(path->usConnObjectId);
 
if (!radeon_atom_apply_quirks
(dev, le16_to_cpu(path->usDeviceTag), &connector_type,
&ddc_bus, &conn_id))
&ddc_bus, &conn_id, &hpd))
continue;
 
radeon_add_atom_connector(dev,
447,7 → 566,8
usDeviceTag),
connector_type, &ddc_bus,
linkb, igp_lane_info,
connector_object_id);
connector_object_id,
&hpd);
 
}
}
502,6 → 622,7
uint16_t devices;
int connector_type;
struct radeon_i2c_bus_rec ddc_bus;
struct radeon_hpd hpd;
};
 
bool radeon_get_atom_connector_info_from_supported_devices_table(struct
517,7 → 638,7
uint16_t device_support;
uint8_t dac;
union atom_supported_devices *supported_devices;
int i, j;
int i, j, max_device;
struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
 
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
527,7 → 648,12
 
device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
 
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
if (frev > 1)
max_device = ATOM_MAX_SUPPORTED_DEVICE;
else
max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;
 
for (i = 0; i < max_device; i++) {
ATOM_CONNECTOR_INFO_I2C ci =
supported_devices->info.asConnInfo[i];
 
553,22 → 679,8
 
dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
 
if ((rdev->family == CHIP_RS690) ||
(rdev->family == CHIP_RS740)) {
if ((i == ATOM_DEVICE_DFP2_INDEX)
&& (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 2))
bios_connectors[i].line_mux =
ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1;
else if ((i == ATOM_DEVICE_DFP3_INDEX)
&& (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 1))
bios_connectors[i].line_mux =
ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1;
else
bios_connectors[i].line_mux =
ci.sucI2cId.sbfAccess.bfI2C_LineMux;
} else
bios_connectors[i].line_mux =
ci.sucI2cId.sbfAccess.bfI2C_LineMux;
ci.sucI2cId.ucAccess;
 
/* give tv unique connector ids */
if (i == ATOM_DEVICE_TV1_INDEX) {
582,9 → 694,31
bios_connectors[i].line_mux = 52;
} else
bios_connectors[i].ddc_bus =
radeon_lookup_gpio(dev,
radeon_lookup_i2c_gpio(rdev,
bios_connectors[i].line_mux);
 
if ((crev > 1) && (frev > 1)) {
u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;
switch (isb) {
case 0x4:
bios_connectors[i].hpd.hpd = RADEON_HPD_1;
break;
case 0xa:
bios_connectors[i].hpd.hpd = RADEON_HPD_2;
break;
default:
bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
break;
}
} else {
if (i == ATOM_DEVICE_DFP1_INDEX)
bios_connectors[i].hpd.hpd = RADEON_HPD_1;
else if (i == ATOM_DEVICE_DFP2_INDEX)
bios_connectors[i].hpd.hpd = RADEON_HPD_2;
else
bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
}
 
/* Always set the connector type to VGA for CRT1/CRT2. if they are
* shared with a DVI port, we'll pick up the DVI connector when we
* merge the outputs. Some bioses incorrectly list VGA ports as DVI.
595,7 → 729,8
 
if (!radeon_atom_apply_quirks
(dev, (1 << i), &bios_connectors[i].connector_type,
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux))
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,
&bios_connectors[i].hpd))
continue;
 
bios_connectors[i].valid = true;
617,9 → 752,9
}
 
/* combine shared connectors */
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
for (i = 0; i < max_device; i++) {
if (bios_connectors[i].valid) {
for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
for (j = 0; j < max_device; j++) {
if (bios_connectors[j].valid && (i != j)) {
if (bios_connectors[i].line_mux ==
bios_connectors[j].line_mux) {
643,6 → 778,10
bios_connectors[i].
connector_type =
DRM_MODE_CONNECTOR_DVII;
if (bios_connectors[j].devices &
(ATOM_DEVICE_DFP_SUPPORT))
bios_connectors[i].hpd =
bios_connectors[j].hpd;
bios_connectors[j].
valid = false;
}
653,7 → 792,7
}
 
/* add the connectors */
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
for (i = 0; i < max_device; i++) {
if (bios_connectors[i].valid) {
uint16_t connector_object_id =
atombios_get_connector_object_id(dev,
666,7 → 805,8
connector_type,
&bios_connectors[i].ddc_bus,
false, 0,
connector_object_id);
connector_object_id,
&bios_connectors[i].hpd);
}
}
 
731,6 → 871,7
* pre-DCE 3.0 r6xx hardware. This might need to be adjusted per
* family.
*/
if (!radeon_new_pll)
p1pll->pll_out_min = 64800;
}
 
861,6 → 1002,7
struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
uint8_t frev, crev;
struct radeon_atom_ss *ss = NULL;
int i;
 
if (id > ATOM_MAX_SS_ENTRY)
return NULL;
878,13 → 1020,18
if (!ss)
return NULL;
 
ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage);
ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType;
ss->step = ss_info->asSS_Info[id].ucSS_Step;
ss->delay = ss_info->asSS_Info[id].ucSS_Delay;
ss->range = ss_info->asSS_Info[id].ucSS_Range;
ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div;
for (i = 0; i < ATOM_MAX_SS_ENTRY; i++) {
if (ss_info->asSS_Info[i].ucSS_Id == id) {
ss->percentage =
le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage);
ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType;
ss->step = ss_info->asSS_Info[i].ucSS_Step;
ss->delay = ss_info->asSS_Info[i].ucSS_Delay;
ss->range = ss_info->asSS_Info[i].ucSS_Range;
ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div;
}
}
}
return ss;
}
 
901,7 → 1048,7
struct radeon_device *rdev = dev->dev_private;
struct radeon_mode_info *mode_info = &rdev->mode_info;
int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
uint16_t data_offset;
uint16_t data_offset, misc;
union lvds_info *lvds_info;
uint8_t frev, crev;
struct radeon_encoder_atom_dig *lvds = NULL;
940,6 → 1087,19
lvds->panel_pwr_delay =
le16_to_cpu(lvds_info->info.usOffDelayInMs);
lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
 
misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);
if (misc & ATOM_VSYNC_POLARITY)
lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;
if (misc & ATOM_HSYNC_POLARITY)
lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;
if (misc & ATOM_COMPOSITESYNC)
lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;
if (misc & ATOM_INTERLACE)
lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;
if (misc & ATOM_DOUBLE_CLOCK_MODE)
lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
 
/* set crtc values */
drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
 
/drivers/video/drm/radeon/radeon_clocks.c
44,6 → 44,10
 
ref_div =
RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
 
if (ref_div == 0)
return 0;
 
sclk = fb_div / ref_div;
 
post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
70,6 → 74,10
 
ref_div =
RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
 
if (ref_div == 0)
return 0;
 
mclk = fb_div / ref_div;
 
post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
98,8 → 106,19
ret = radeon_combios_get_clock_info(dev);
 
if (ret) {
if (p1pll->reference_div < 2) {
if (!ASIC_IS_AVIVO(rdev)) {
u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
if (ASIC_IS_R300(rdev))
p1pll->reference_div =
(tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
else
p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
if (p1pll->reference_div < 2)
p1pll->reference_div = 12;
} else
p1pll->reference_div = 12;
}
if (p2pll->reference_div < 2)
p2pll->reference_div = 12;
if (rdev->family < CHIP_RS600) {
/drivers/video/drm/radeon/radeon_combios.c
50,7 → 50,8
uint32_t supported_device,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
uint16_t connector_object_id);
uint16_t connector_object_id,
struct radeon_hpd *hpd);
 
/* from radeon_legacy_encoder.c */
extern void
442,39 → 443,71
 
}
 
struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
int ddc_line)
{
struct radeon_i2c_bus_rec i2c;
 
if (ddc_line == RADEON_GPIOPAD_MASK) {
i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
i2c.a_clk_reg = RADEON_GPIOPAD_A;
i2c.a_data_reg = RADEON_GPIOPAD_A;
i2c.en_clk_reg = RADEON_GPIOPAD_EN;
i2c.en_data_reg = RADEON_GPIOPAD_EN;
i2c.y_clk_reg = RADEON_GPIOPAD_Y;
i2c.y_data_reg = RADEON_GPIOPAD_Y;
} else if (ddc_line == RADEON_MDGPIO_MASK) {
i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
i2c.mask_data_reg = RADEON_MDGPIO_MASK;
i2c.a_clk_reg = RADEON_MDGPIO_A;
i2c.a_data_reg = RADEON_MDGPIO_A;
i2c.en_clk_reg = RADEON_MDGPIO_EN;
i2c.en_data_reg = RADEON_MDGPIO_EN;
i2c.y_clk_reg = RADEON_MDGPIO_Y;
i2c.y_data_reg = RADEON_MDGPIO_Y;
} else {
i2c.mask_clk_mask = RADEON_GPIO_EN_1;
i2c.mask_data_mask = RADEON_GPIO_EN_0;
i2c.a_clk_mask = RADEON_GPIO_A_1;
i2c.a_data_mask = RADEON_GPIO_A_0;
i2c.put_clk_mask = RADEON_GPIO_EN_1;
i2c.put_data_mask = RADEON_GPIO_EN_0;
i2c.get_clk_mask = RADEON_GPIO_Y_1;
i2c.get_data_mask = RADEON_GPIO_Y_0;
if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
(ddc_line == RADEON_MDGPIO_EN_REG)) {
i2c.en_clk_mask = RADEON_GPIO_EN_1;
i2c.en_data_mask = RADEON_GPIO_EN_0;
i2c.y_clk_mask = RADEON_GPIO_Y_1;
i2c.y_data_mask = RADEON_GPIO_Y_0;
 
i2c.mask_clk_reg = ddc_line;
i2c.mask_data_reg = ddc_line;
i2c.a_clk_reg = ddc_line;
i2c.a_data_reg = ddc_line;
i2c.put_clk_reg = ddc_line;
i2c.put_data_reg = ddc_line;
i2c.get_clk_reg = ddc_line + 4;
i2c.get_data_reg = ddc_line + 4;
} else {
i2c.mask_clk_reg = ddc_line;
i2c.mask_data_reg = ddc_line;
i2c.a_clk_reg = ddc_line;
i2c.a_data_reg = ddc_line;
i2c.put_clk_reg = ddc_line;
i2c.put_data_reg = ddc_line;
i2c.get_clk_reg = ddc_line;
i2c.get_data_reg = ddc_line;
i2c.en_clk_reg = ddc_line;
i2c.en_data_reg = ddc_line;
i2c.y_clk_reg = ddc_line;
i2c.y_data_reg = ddc_line;
}
 
if (rdev->family < CHIP_R200)
i2c.hw_capable = false;
else {
switch (ddc_line) {
case RADEON_GPIO_VGA_DDC:
case RADEON_GPIO_DVI_DDC:
i2c.hw_capable = true;
break;
case RADEON_GPIO_MONID:
/* hw i2c on RADEON_GPIO_MONID doesn't seem to work
* reliably on some pre-r4xx hardware; not sure why.
*/
i2c.hw_capable = false;
break;
default:
i2c.hw_capable = false;
break;
}
}
i2c.mm_i2c = false;
i2c.i2c_id = 0;
 
if (ddc_line)
i2c.valid = true;
else
495,7 → 528,7
uint16_t sclk, mclk;
 
if (rdev->bios == NULL)
return NULL;
return false;
 
pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
if (pll_info) {
993,8 → 1026,8
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS400 */
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */
{ {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */
{ {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */
};
 
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
1028,7 → 1061,6
tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
 
if (tmds_info) {
 
ver = RBIOS8(tmds_info);
DRM_INFO("DFP table revision: %d\n", ver);
if (ver == 3) {
1063,51 → 1095,139
tmds->tmds_pll[i].value);
}
}
} else
} else {
DRM_INFO("No TMDS info found in BIOS\n");
return false;
}
return true;
}
 
struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds)
{
struct radeon_encoder_int_tmds *tmds = NULL;
bool ret;
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_i2c_bus_rec i2c_bus;
 
tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
/* default for macs */
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
 
if (!tmds)
return NULL;
/* XXX some macs have duallink chips */
switch (rdev->mode_info.connector_table) {
case CT_POWERBOOK_EXTERNAL:
case CT_MINI_EXTERNAL:
default:
tmds->dvo_chip = DVO_SIL164;
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
break;
}
 
ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
if (ret == false)
radeon_legacy_get_tmds_info_from_table(encoder, tmds);
 
return tmds;
return true;
}
 
void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder)
bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds)
{
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
uint16_t ext_tmds_info;
uint8_t ver;
uint16_t offset;
uint8_t ver, id, blocks, clk, data;
int i;
enum radeon_combios_ddc gpio;
struct radeon_i2c_bus_rec i2c_bus;
 
if (rdev->bios == NULL)
return;
return false;
 
ext_tmds_info =
combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
if (ext_tmds_info) {
ver = RBIOS8(ext_tmds_info);
tmds->i2c_bus = NULL;
if (rdev->flags & RADEON_IS_IGP) {
offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
if (offset) {
ver = RBIOS8(offset);
DRM_INFO("GPIO Table revision: %d\n", ver);
blocks = RBIOS8(offset + 2);
for (i = 0; i < blocks; i++) {
id = RBIOS8(offset + 3 + (i * 5) + 0);
if (id == 136) {
clk = RBIOS8(offset + 3 + (i * 5) + 3);
data = RBIOS8(offset + 3 + (i * 5) + 4);
i2c_bus.valid = true;
i2c_bus.mask_clk_mask = (1 << clk);
i2c_bus.mask_data_mask = (1 << data);
i2c_bus.a_clk_mask = (1 << clk);
i2c_bus.a_data_mask = (1 << data);
i2c_bus.en_clk_mask = (1 << clk);
i2c_bus.en_data_mask = (1 << data);
i2c_bus.y_clk_mask = (1 << clk);
i2c_bus.y_data_mask = (1 << data);
i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK;
i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK;
i2c_bus.a_clk_reg = RADEON_GPIOPAD_A;
i2c_bus.a_data_reg = RADEON_GPIOPAD_A;
i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN;
i2c_bus.en_data_reg = RADEON_GPIOPAD_EN;
i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y;
i2c_bus.y_data_reg = RADEON_GPIOPAD_Y;
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
tmds->dvo_chip = DVO_SIL164;
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
break;
}
}
}
} else {
offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
if (offset) {
ver = RBIOS8(offset);
DRM_INFO("External TMDS Table revision: %d\n", ver);
// TODO
tmds->slave_addr = RBIOS8(offset + 4 + 2);
tmds->slave_addr >>= 1; /* 7 bit addressing */
gpio = RBIOS8(offset + 4 + 3);
switch (gpio) {
case DDC_MONID:
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_DVI:
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_VGA:
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_CRT2:
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
if (rdev->family >= CHIP_R300)
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
else
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_LCD: /* MM i2c */
DRM_ERROR("MM i2c requires hw i2c engine\n");
break;
default:
DRM_ERROR("Unsupported gpio %d\n", gpio);
break;
}
}
}
 
if (!tmds->i2c_bus) {
DRM_INFO("No valid Ext TMDS info found in BIOS\n");
return false;
}
 
return true;
}
 
bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
struct radeon_i2c_bus_rec ddc_i2c;
struct radeon_hpd hpd;
 
rdev->mode_info.connector_table = radeon_connector_table;
if (rdev->mode_info.connector_table == CT_NONE) {
1168,7 → 1288,8
/* these are the most common settings */
if (rdev->flags & RADEON_SINGLE_CRTC) {
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1178,10 → 1299,12
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
&ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
} else if (rdev->flags & RADEON_IS_MOBILITY) {
/* LVDS */
ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
ddc_i2c = combios_setup_i2c_bus(rdev, 0);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
1191,10 → 1314,12
ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS,
&ddc_i2c,
CONNECTOR_OBJECT_ID_LVDS);
CONNECTOR_OBJECT_ID_LVDS,
&hpd);
 
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1204,10 → 1329,12
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
&ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
} else {
/* DVI-I - tv dac, int tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_1;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
1223,10 → 1350,12
ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_DVII,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
&hpd);
 
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1236,11 → 1365,14
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
&ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
}
 
if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
/* TV - tv dac */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1250,7 → 1382,8
ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
}
break;
case CT_IBOOK:
1257,7 → 1390,8
DRM_INFO("Connector Table: %d (ibook)\n",
rdev->mode_info.connector_table);
/* LVDS */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
1265,9 → 1399,11
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
CONNECTOR_OBJECT_ID_LVDS);
CONNECTOR_OBJECT_ID_LVDS,
&hpd);
/* VGA - TV DAC */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
1275,8 → 1411,11
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1285,13 → 1424,15
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_POWERBOOK_EXTERNAL:
DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
rdev->mode_info.connector_table);
/* LVDS */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
1299,9 → 1440,11
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
CONNECTOR_OBJECT_ID_LVDS);
CONNECTOR_OBJECT_ID_LVDS,
&hpd);
/* DVI-I - primary dac, ext tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_2; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP2_SUPPORT,
1317,8 → 1460,11
ATOM_DEVICE_DFP2_SUPPORT |
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I);
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1327,13 → 1473,15
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_POWERBOOK_INTERNAL:
DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
rdev->mode_info.connector_table);
/* LVDS */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
1341,9 → 1489,11
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
CONNECTOR_OBJECT_ID_LVDS);
CONNECTOR_OBJECT_ID_LVDS,
&hpd);
/* DVI-I - primary dac, int tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
1358,8 → 1508,11
ATOM_DEVICE_DFP1_SUPPORT |
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1368,13 → 1521,15
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_POWERBOOK_VGA:
DRM_INFO("Connector Table: %d (powerbook vga)\n",
rdev->mode_info.connector_table);
/* LVDS */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_LCD1_SUPPORT,
1382,9 → 1537,11
ATOM_DEVICE_LCD1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
CONNECTOR_OBJECT_ID_LVDS);
CONNECTOR_OBJECT_ID_LVDS,
&hpd);
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1392,8 → 1549,11
ATOM_DEVICE_CRT1_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1402,13 → 1562,15
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_MINI_EXTERNAL:
DRM_INFO("Connector Table: %d (mini external tmds)\n",
rdev->mode_info.connector_table);
/* DVI-I - tv dac, ext tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
hpd.hpd = RADEON_HPD_2; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP2_SUPPORT,
1424,8 → 1586,11
ATOM_DEVICE_DFP2_SUPPORT |
ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1434,13 → 1599,15
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_MINI_INTERNAL:
DRM_INFO("Connector Table: %d (mini internal tmds)\n",
rdev->mode_info.connector_table);
/* DVI-I - tv dac, int tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
1455,8 → 1622,11
ATOM_DEVICE_DFP1_SUPPORT |
ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1465,13 → 1635,15
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_IMAC_G5_ISIGHT:
DRM_INFO("Connector Table: %d (imac g5 isight)\n",
rdev->mode_info.connector_table);
/* DVI-D - int tmds */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_DFP1_SUPPORT,
1479,9 → 1651,11
ATOM_DEVICE_DFP1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
&hpd);
/* VGA - tv dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
1489,8 → 1663,11
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1499,13 → 1676,15
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
case CT_EMAC:
DRM_INFO("Connector Table: %d (emac)\n",
rdev->mode_info.connector_table);
/* VGA - primary dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1513,9 → 1692,11
ATOM_DEVICE_CRT1_SUPPORT);
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
/* VGA - tv dac */
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_CRT2_SUPPORT,
1523,8 → 1704,11
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
/* TV - TV DAC */
ddc_i2c.valid = false;
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id(dev,
ATOM_DEVICE_TV1_SUPPORT,
1533,7 → 1717,8
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
default:
DRM_INFO("Connector table: %d (invalid)\n",
1550,7 → 1735,8
int bios_index,
enum radeon_combios_connector
*legacy_connector,
struct radeon_i2c_bus_rec *ddc_i2c)
struct radeon_i2c_bus_rec *ddc_i2c,
struct radeon_hpd *hpd)
{
struct radeon_device *rdev = dev->dev_private;
 
1558,29 → 1744,26
if ((rdev->family == CHIP_RS400 ||
rdev->family == CHIP_RS480) &&
ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
*ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
else if ((rdev->family == CHIP_RS400 ||
rdev->family == CHIP_RS480) &&
ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) {
ddc_i2c->valid = true;
*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK);
ddc_i2c->mask_clk_mask = (0x20 << 8);
ddc_i2c->mask_data_mask = 0x80;
ddc_i2c->a_clk_mask = (0x20 << 8);
ddc_i2c->a_data_mask = 0x80;
ddc_i2c->put_clk_mask = (0x20 << 8);
ddc_i2c->put_data_mask = 0x80;
ddc_i2c->get_clk_mask = (0x20 << 8);
ddc_i2c->get_data_mask = 0x80;
ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK;
ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK;
ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A;
ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
ddc_i2c->put_clk_reg = RADEON_GPIOPAD_EN;
ddc_i2c->put_data_reg = RADEON_GPIOPAD_EN;
ddc_i2c->get_clk_reg = RADEON_LCD_GPIO_Y_REG;
ddc_i2c->get_data_reg = RADEON_LCD_GPIO_Y_REG;
ddc_i2c->en_clk_mask = (0x20 << 8);
ddc_i2c->en_data_mask = 0x80;
ddc_i2c->y_clk_mask = (0x20 << 8);
ddc_i2c->y_data_mask = 0x80;
}
 
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
if ((rdev->family >= CHIP_R300) &&
ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
 
/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
if (dev->pdev->device == 0x515e &&
1624,6 → 1807,12
dev->pdev->subsystem_device == 0x280a)
return false;
 
/* MSI S270 has non-existent TV port */
if (dev->pdev->device == 0x5955 &&
dev->pdev->subsystem_vendor == 0x1462 &&
dev->pdev->subsystem_device == 0x0131)
return false;
 
return true;
}
 
1671,6 → 1860,7
enum radeon_combios_connector connector;
int i = 0;
struct radeon_i2c_bus_rec ddc_i2c;
struct radeon_hpd hpd;
 
if (rdev->bios == NULL)
return false;
1691,26 → 1881,40
switch (ddc_type) {
case DDC_MONID:
ddc_i2c =
combios_setup_i2c_bus(RADEON_GPIO_MONID);
combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
break;
case DDC_DVI:
ddc_i2c =
combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
break;
case DDC_VGA:
ddc_i2c =
combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
break;
case DDC_CRT2:
ddc_i2c =
combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
break;
default:
break;
}
 
switch (connector) {
case CONNECTOR_PROPRIETARY_LEGACY:
case CONNECTOR_DVI_I_LEGACY:
case CONNECTOR_DVI_D_LEGACY:
if ((tmp >> 4) & 0x1)
hpd.hpd = RADEON_HPD_2;
else
hpd.hpd = RADEON_HPD_1;
break;
default:
hpd.hpd = RADEON_HPD_NONE;
break;
}
 
if (!radeon_apply_legacy_quirks(dev, i, &connector,
&ddc_i2c))
&ddc_i2c, &hpd))
continue;
 
switch (connector) {
1727,7 → 1931,8
legacy_connector_convert
[connector],
&ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
&hpd);
break;
case CONNECTOR_CRT_LEGACY:
if (tmp & 0x1) {
1753,7 → 1958,8
legacy_connector_convert
[connector],
&ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
break;
case CONNECTOR_DVI_I_LEGACY:
devices = 0;
1799,7 → 2005,8
legacy_connector_convert
[connector],
&ddc_i2c,
connector_object_id);
connector_object_id,
&hpd);
break;
case CONNECTOR_DVI_D_LEGACY:
if ((tmp >> 4) & 0x1) {
1817,7 → 2024,8
legacy_connector_convert
[connector],
&ddc_i2c,
connector_object_id);
connector_object_id,
&hpd);
break;
case CONNECTOR_CTV_LEGACY:
case CONNECTOR_STV_LEGACY:
1832,7 → 2040,8
legacy_connector_convert
[connector],
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
break;
default:
DRM_ERROR("Unknown connector type: %d\n",
1858,7 → 2067,8
0),
ATOM_DEVICE_DFP1_SUPPORT);
 
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_connector(dev,
0,
ATOM_DEVICE_CRT1_SUPPORT |
1865,7 → 2075,8
ATOM_DEVICE_DFP1_SUPPORT,
DRM_MODE_CONNECTOR_DVII,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
&hpd);
} else {
uint16_t crt_info =
combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
1876,13 → 2087,15
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_connector(dev,
0,
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_VGA,
&ddc_i2c,
CONNECTOR_OBJECT_ID_VGA);
CONNECTOR_OBJECT_ID_VGA,
&hpd);
} else {
DRM_DEBUG("No connector info found\n");
return false;
1910,27 → 2123,27
case DDC_MONID:
ddc_i2c =
combios_setup_i2c_bus
(RADEON_GPIO_MONID);
(rdev, RADEON_GPIO_MONID);
break;
case DDC_DVI:
ddc_i2c =
combios_setup_i2c_bus
(RADEON_GPIO_DVI_DDC);
(rdev, RADEON_GPIO_DVI_DDC);
break;
case DDC_VGA:
ddc_i2c =
combios_setup_i2c_bus
(RADEON_GPIO_VGA_DDC);
(rdev, RADEON_GPIO_VGA_DDC);
break;
case DDC_CRT2:
ddc_i2c =
combios_setup_i2c_bus
(RADEON_GPIO_CRT2_DDC);
(rdev, RADEON_GPIO_CRT2_DDC);
break;
case DDC_LCD:
ddc_i2c =
combios_setup_i2c_bus
(RADEON_LCD_GPIO_MASK);
(rdev, RADEON_GPIOPAD_MASK);
ddc_i2c.mask_clk_mask =
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.mask_data_mask =
1939,19 → 2152,19
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.a_data_mask =
RBIOS32(lcd_ddc_info + 7);
ddc_i2c.put_clk_mask =
ddc_i2c.en_clk_mask =
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.put_data_mask =
ddc_i2c.en_data_mask =
RBIOS32(lcd_ddc_info + 7);
ddc_i2c.get_clk_mask =
ddc_i2c.y_clk_mask =
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.get_data_mask =
ddc_i2c.y_data_mask =
RBIOS32(lcd_ddc_info + 7);
break;
case DDC_GPIO:
ddc_i2c =
combios_setup_i2c_bus
(RADEON_MDGPIO_EN_REG);
(rdev, RADEON_MDGPIO_MASK);
ddc_i2c.mask_clk_mask =
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.mask_data_mask =
1960,13 → 2173,13
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.a_data_mask =
RBIOS32(lcd_ddc_info + 7);
ddc_i2c.put_clk_mask =
ddc_i2c.en_clk_mask =
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.put_data_mask =
ddc_i2c.en_data_mask =
RBIOS32(lcd_ddc_info + 7);
ddc_i2c.get_clk_mask =
ddc_i2c.y_clk_mask =
RBIOS32(lcd_ddc_info + 3);
ddc_i2c.get_data_mask =
ddc_i2c.y_data_mask =
RBIOS32(lcd_ddc_info + 7);
break;
default:
1977,12 → 2190,14
} else
ddc_i2c.valid = false;
 
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_connector(dev,
5,
ATOM_DEVICE_LCD1_SUPPORT,
DRM_MODE_CONNECTOR_LVDS,
&ddc_i2c,
CONNECTOR_OBJECT_ID_LVDS);
CONNECTOR_OBJECT_ID_LVDS,
&hpd);
}
}
 
1993,6 → 2208,7
if (tv_info) {
if (RBIOS8(tv_info + 6) == 'T') {
if (radeon_apply_legacy_tv_quirks(dev)) {
hpd.hpd = RADEON_HPD_NONE;
radeon_add_legacy_encoder(dev,
radeon_get_encoder_id
(dev,
2003,7 → 2219,8
ATOM_DEVICE_TV1_SUPPORT,
DRM_MODE_CONNECTOR_SVIDEO,
&ddc_i2c,
CONNECTOR_OBJECT_ID_SVIDEO);
CONNECTOR_OBJECT_ID_SVIDEO,
&hpd);
}
}
}
2014,6 → 2231,193
return true;
}
 
void radeon_external_tmds_setup(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
 
if (!tmds)
return;
 
switch (tmds->dvo_chip) {
case DVO_SIL164:
/* sil 164 */
radeon_i2c_do_lock(tmds->i2c_bus, 1);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x08, 0x30);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x09, 0x00);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x0a, 0x90);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x0c, 0x89);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x08, 0x3b);
radeon_i2c_do_lock(tmds->i2c_bus, 0);
break;
case DVO_SIL1178:
/* sil 1178 - untested */
/*
* 0x0f, 0x44
* 0x0f, 0x4c
* 0x0e, 0x01
* 0x0a, 0x80
* 0x09, 0x30
* 0x0c, 0xc9
* 0x0d, 0x70
* 0x08, 0x32
* 0x08, 0x33
*/
break;
default:
break;
}
 
}
 
bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
uint16_t offset;
uint8_t blocks, slave_addr, rev;
uint32_t index, id;
uint32_t reg, val, and_mask, or_mask;
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
 
if (rdev->bios == NULL)
return false;
 
if (!tmds)
return false;
 
if (rdev->flags & RADEON_IS_IGP) {
offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
rev = RBIOS8(offset);
if (offset) {
rev = RBIOS8(offset);
if (rev > 1) {
blocks = RBIOS8(offset + 3);
index = offset + 4;
while (blocks > 0) {
id = RBIOS16(index);
index += 2;
switch (id >> 13) {
case 0:
reg = (id & 0x1fff) * 4;
val = RBIOS32(index);
index += 4;
WREG32(reg, val);
break;
case 2:
reg = (id & 0x1fff) * 4;
and_mask = RBIOS32(index);
index += 4;
or_mask = RBIOS32(index);
index += 4;
val = RREG32(reg);
val = (val & and_mask) | or_mask;
WREG32(reg, val);
break;
case 3:
val = RBIOS16(index);
index += 2;
udelay(val);
break;
case 4:
val = RBIOS16(index);
index += 2;
udelay(val * 1000);
break;
case 6:
slave_addr = id & 0xff;
slave_addr >>= 1; /* 7 bit addressing */
index++;
reg = RBIOS8(index);
index++;
val = RBIOS8(index);
index++;
radeon_i2c_do_lock(tmds->i2c_bus, 1);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
slave_addr,
reg, val);
radeon_i2c_do_lock(tmds->i2c_bus, 0);
break;
default:
DRM_ERROR("Unknown id %d\n", id >> 13);
break;
}
blocks--;
}
return true;
}
}
} else {
offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
if (offset) {
index = offset + 10;
id = RBIOS16(index);
while (id != 0xffff) {
index += 2;
switch (id >> 13) {
case 0:
reg = (id & 0x1fff) * 4;
val = RBIOS32(index);
WREG32(reg, val);
break;
case 2:
reg = (id & 0x1fff) * 4;
and_mask = RBIOS32(index);
index += 4;
or_mask = RBIOS32(index);
index += 4;
val = RREG32(reg);
val = (val & and_mask) | or_mask;
WREG32(reg, val);
break;
case 4:
val = RBIOS16(index);
index += 2;
udelay(val);
break;
case 5:
reg = id & 0x1fff;
and_mask = RBIOS32(index);
index += 4;
or_mask = RBIOS32(index);
index += 4;
val = RREG32_PLL(reg);
val = (val & and_mask) | or_mask;
WREG32_PLL(reg, val);
break;
case 6:
reg = id & 0x1fff;
val = RBIOS8(index);
index += 1;
radeon_i2c_do_lock(tmds->i2c_bus, 1);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
reg, val);
radeon_i2c_do_lock(tmds->i2c_bus, 0);
break;
default:
DRM_ERROR("Unknown id %d\n", id >> 13);
break;
}
id = RBIOS16(index);
}
return true;
}
}
return false;
}
 
static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
{
struct radeon_device *rdev = dev->dev_private;
/drivers/video/drm/radeon/radeon_connectors.c
40,6 → 40,26
struct drm_encoder *encoder,
bool connected);
 
void radeon_connector_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
 
if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
if (radeon_dp_needs_link_train(radeon_connector)) {
if (connector->encoder)
dp_link_train(connector->encoder, connector);
}
}
}
 
}
 
static void radeon_property_change_mode(struct drm_encoder *encoder)
{
struct drm_crtc *crtc = encoder->crtc;
445,10 → 465,10
ret = connector_status_connected;
else {
if (radeon_connector->ddc_bus) {
radeon_i2c_do_lock(radeon_connector, 1);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
&radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (radeon_connector->edid)
ret = connector_status_connected;
}
553,17 → 573,17
if (!encoder)
ret = connector_status_disconnected;
 
radeon_i2c_do_lock(radeon_connector, 1);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
dret = radeon_ddc_probe(radeon_connector);
radeon_i2c_do_lock(radeon_connector, 0);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (dret) {
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
}
radeon_i2c_do_lock(radeon_connector, 1);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
708,17 → 728,17
enum drm_connector_status ret = connector_status_disconnected;
bool dret;
 
radeon_i2c_do_lock(radeon_connector, 1);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
dret = radeon_ddc_probe(radeon_connector);
radeon_i2c_do_lock(radeon_connector, 0);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (dret) {
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
}
radeon_i2c_do_lock(radeon_connector, 1);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0);
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
735,8 → 755,41
ret = connector_status_disconnected;
} else
ret = connector_status_connected;
 
/* multiple connectors on the same encoder with the same ddc line
* This tends to be HDMI and DVI on the same encoder with the
* same ddc line. If the edid says HDMI, consider the HDMI port
* connected and the DVI port disconnected. If the edid doesn't
* say HDMI, vice versa.
*/
if (radeon_connector->shared_ddc && connector_status_connected) {
struct drm_device *dev = connector->dev;
struct drm_connector *list_connector;
struct radeon_connector *list_radeon_connector;
list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
if (connector == list_connector)
continue;
list_radeon_connector = to_radeon_connector(list_connector);
if (radeon_connector->devices == list_radeon_connector->devices) {
if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
ret = connector_status_disconnected;
}
} else {
if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
(connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
ret = connector_status_disconnected;
}
}
}
}
}
}
}
 
if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
goto out;
863,6 → 916,91
.force = radeon_dvi_force,
};
 
static void radeon_dp_connector_destroy(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
 
if (radeon_connector->ddc_bus)
radeon_i2c_destroy(radeon_connector->ddc_bus);
if (radeon_connector->edid)
kfree(radeon_connector->edid);
if (radeon_dig_connector->dp_i2c_bus)
radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
kfree(radeon_connector->con_priv);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
 
static int radeon_dp_get_modes(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
int ret;
 
ret = radeon_ddc_get_modes(radeon_connector);
return ret;
}
 
static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected;
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
u8 sink_type;
 
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
}
 
sink_type = radeon_dp_getsinktype(radeon_connector);
if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
if (radeon_dp_getdpcd(radeon_connector)) {
radeon_dig_connector->dp_sink_type = sink_type;
ret = connector_status_connected;
}
} else {
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
if (radeon_ddc_probe(radeon_connector)) {
radeon_dig_connector->dp_sink_type = sink_type;
ret = connector_status_connected;
}
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
}
 
return ret;
}
 
static int radeon_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
 
/* XXX check mode bandwidth */
 
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
return radeon_dp_mode_valid_helper(radeon_connector, mode);
else
return MODE_OK;
}
 
struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
.get_modes = radeon_dp_get_modes,
.mode_valid = radeon_dp_mode_valid,
.best_encoder = radeon_dvi_encoder,
};
 
struct drm_connector_funcs radeon_dp_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_connector_set_property,
.destroy = radeon_dp_connector_destroy,
.force = radeon_dvi_force,
};
 
void
radeon_add_atom_connector(struct drm_device *dev,
uint32_t connector_id,
871,7 → 1009,8
struct radeon_i2c_bus_rec *i2c_bus,
bool linkb,
uint32_t igp_lane_info,
uint16_t connector_object_id)
uint16_t connector_object_id,
struct radeon_hpd *hpd)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
911,6 → 1050,7
radeon_connector->devices = supported_device;
radeon_connector->shared_ddc = shared_ddc;
radeon_connector->connector_object_id = connector_object_id;
radeon_connector->hpd = *hpd;
switch (connector_type) {
case DRM_MODE_CONNECTOR_VGA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
963,10 → 1103,12
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.coherent_mode_property,
1);
if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
}
break;
case DRM_MODE_CONNECTOR_HDMIA:
case DRM_MODE_CONNECTOR_HDMIB:
997,16 → 1139,23
radeon_dig_connector->linkb = linkb;
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
if (ret)
goto failed;
if (i2c_bus->valid) {
/* add DP i2c bus */
radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
if (!radeon_dig_connector->dp_i2c_bus)
goto failed;
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
if (!radeon_connector->ddc_bus)
goto failed;
}
subpixel_order = SubPixelHorizontalRGB;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.coherent_mode_property,
1);
break;
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
1020,6 → 1169,9
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.tv_std_property,
1);
}
break;
case DRM_MODE_CONNECTOR_LVDS:
1038,7 → 1190,6
if (!radeon_connector->ddc_bus)
goto failed;
}
drm_mode_create_scaling_mode_property(dev);
drm_connector_attach_property(&radeon_connector->base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_FULLSCREEN);
1063,7 → 1214,8
uint32_t supported_device,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
uint16_t connector_object_id)
uint16_t connector_object_id,
struct radeon_hpd *hpd)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
1093,6 → 1245,7
radeon_connector->connector_id = connector_id;
radeon_connector->devices = supported_device;
radeon_connector->connector_object_id = connector_object_id;
radeon_connector->hpd = *hpd;
switch (connector_type) {
case DRM_MODE_CONNECTOR_VGA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1160,6 → 1313,9
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.tv_std_property,
1);
}
break;
case DRM_MODE_CONNECTOR_LVDS:
/drivers/video/drm/radeon/radeon_device.c
77,10 → 77,11
if (rdev->family < CHIP_R600) {
int i;
 
for (i = 0; i < 8; i++) {
WREG32(RADEON_SURFACE0_INFO +
i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
0);
for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
if (rdev->surface_regs[i].bo)
radeon_bo_get_surface_reg(rdev->surface_regs[i].bo);
else
radeon_clear_surface_reg(rdev, i);
}
/* enable surfaces */
WREG32(RADEON_SURFACE_CNTL, 0);
241,6 → 242,24
 
}
 
bool radeon_boot_test_post_card(struct radeon_device *rdev)
{
if (radeon_card_posted(rdev))
return true;
 
if (rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
if (rdev->is_atom_bios)
atom_asic_init(rdev->mode_info.atom_context);
else
radeon_combios_asic_init(rdev->ddev);
return true;
} else {
dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
return false;
}
}
 
int radeon_dummy_page_init(struct radeon_device *rdev)
{
rdev->dummy_page.page = AllocPage();
493,12 → 512,16
 
rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
atom_allocate_fb_scratch(rdev->mode_info.atom_context);
return 0;
}
 
void radeon_atombios_fini(struct radeon_device *rdev)
{
if (rdev->mode_info.atom_context) {
kfree(rdev->mode_info.atom_context->scratch);
kfree(rdev->mode_info.atom_context);
}
kfree(rdev->mode_info.atom_card_info);
}
 
581,7 → 604,7
return r;
}
 
if (radeon_agpmode == -1) {
if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
radeon_agp_disable(rdev);
}
 
895,7 → 918,7
return 0;
};
}
dbgprintf("Radeon RC08 cmdline %s\n", cmdline);
dbgprintf("Radeon RC09 cmdline %s\n", cmdline);
 
enum_pci_devices();
 
/drivers/video/drm/radeon/radeon_encoders.c
35,6 → 35,51
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
struct drm_display_mode *mode);
 
static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *clone_encoder;
uint32_t index_mask = 0;
int count;
 
/* DIG routing gets problematic */
if (rdev->family >= CHIP_R600)
return index_mask;
/* LVDS/TV are too wacky */
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
return index_mask;
/* DVO requires 2x ppll clocks depending on tmds chip */
if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
return index_mask;
count = -1;
list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
count++;
 
if (clone_encoder == encoder)
continue;
if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
continue;
if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
continue;
else
index_mask |= (1 << count);
}
return index_mask;
}
 
void radeon_setup_encoder_clones(struct drm_device *dev)
{
struct drm_encoder *encoder;
 
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder->possible_clones = radeon_encoder_clones(encoder);
}
}
 
uint32_t
radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
{
163,29 → 208,6
return NULL;
}
 
/* used for both atom and legacy */
void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
 
if (mode->hdisplay < native_mode->hdisplay ||
mode->vdisplay < native_mode->vdisplay) {
int mode_id = adjusted_mode->base.id;
*adjusted_mode = *native_mode;
if (!ASIC_IS_AVIVO(rdev)) {
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
}
adjusted_mode->base.id = mode_id;
}
}
 
 
static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
198,14 → 220,24
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
 
if (radeon_encoder->rmx_type != RMX_OFF)
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
 
/* hw bug */
if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
/* get the native mode for LVDS */
if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
int mode_id = adjusted_mode->base.id;
*adjusted_mode = *native_mode;
if (!ASIC_IS_AVIVO(rdev)) {
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
}
adjusted_mode->base.id = mode_id;
}
 
/* get the native mode for TV */
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
if (tv_dac) {
218,6 → 250,12
}
}
 
if (ASIC_IS_DCE3(rdev) &&
(radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
radeon_dp_set_link_config(connector, mode);
}
 
return true;
}
 
392,7 → 430,7
LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
};
 
static void
void
atombios_digital_setup(struct drm_encoder *encoder, int action)
{
struct drm_device *dev = encoder->dev;
522,6 → 560,7
{
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *radeon_dig_connector;
 
connector = radeon_get_connector_for_encoder(encoder);
if (!connector)
551,10 → 590,10
return ATOM_ENCODER_MODE_LVDS;
break;
case DRM_MODE_CONNECTOR_DisplayPort:
/*if (radeon_output->MonType == MT_DP)
radeon_dig_connector = radeon_connector->con_priv;
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
return ATOM_ENCODER_MODE_DP;
else*/
if (drm_detect_hdmi_monitor(radeon_connector->edid))
else if (drm_detect_hdmi_monitor(radeon_connector->edid))
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;
573,6 → 612,30
}
}
 
/*
* DIG Encoder/Transmitter Setup
*
* DCE 3.0/3.1
* - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
* Supports up to 3 digital outputs
* - 2 DIG encoder blocks.
* DIG1 can drive UNIPHY link A or link B
* DIG2 can drive UNIPHY link B or LVTMA
*
* DCE 3.2
* - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
* Supports up to 5 digital outputs
* - 2 DIG encoder blocks.
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
*
* Routing
* crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
* Examples:
* crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI
* crtc1 -> dig1 -> UNIPHY0 link B -> DP
* crtc0 -> dig1 -> UNIPHY2 link A -> LVDS
* crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI
*/
static void
atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
{
614,10 → 677,17
} else {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
/* XXX doesn't really matter which dig encoder we pick as long as it's
* not already in use
*/
if (dig_connector->linkb)
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
else
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
num = 1;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* Only dig2 encoder can drive LVTMA */
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
num = 2;
break;
652,19 → 722,22
}
}
 
if (radeon_encoder->pixel_clock > 165000) {
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
args.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
if (dig_connector->dp_clock == 270000)
args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
args.ucLaneNum = dig_connector->dp_lane_count;
} else if (radeon_encoder->pixel_clock > 165000)
args.ucLaneNum = 8;
} else {
else
args.ucLaneNum = 4;
 
if (dig_connector->linkb)
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
else
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
args.ucLaneNum = 4;
}
 
args.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
}
674,8 → 747,8
DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
};
 
static void
atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
void
atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
687,6 → 760,7
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *dig_connector;
bool is_dp = false;
 
connector = radeon_get_connector_for_encoder(encoder);
if (!connector)
704,6 → 778,9
 
dig_connector = radeon_connector->con_priv;
 
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
is_dp = true;
 
memset(&args, 0, sizeof(args));
 
if (ASIC_IS_DCE32(rdev))
724,17 → 801,23
args.v1.ucAction = action;
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
args.v1.usInitInfo = radeon_connector->connector_object_id;
} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
args.v1.asMode.ucLaneSel = lane_num;
args.v1.asMode.ucLaneSet = lane_set;
} else {
if (radeon_encoder->pixel_clock > 165000)
if (is_dp)
args.v1.usPixelClock =
cpu_to_le16(dig_connector->dp_clock / 10);
else if (radeon_encoder->pixel_clock > 165000)
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
}
if (ASIC_IS_DCE32(rdev)) {
if (radeon_encoder->pixel_clock > 165000)
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
if (dig->dig_block)
args.v2.acConfig.ucEncoderSel = 1;
if (dig_connector->linkb)
args.v2.acConfig.ucLinkSel = 1;
 
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
751,7 → 834,9
break;
}
 
if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (is_dp)
args.v2.acConfig.fCoherentMode = 1;
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v2.acConfig.fCoherentMode = 1;
}
760,17 → 845,20
 
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
/* XXX doesn't really matter which dig encoder we pick as long as it's
* not already in use
*/
if (dig_connector->linkb)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
else
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
if (rdev->flags & RADEON_IS_IGP) {
if (radeon_encoder->pixel_clock > 165000) {
args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
ATOM_TRANSMITTER_CONFIG_LINKA_B);
if (dig_connector->igp_lane_info & 0x3)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
else if (dig_connector->igp_lane_info & 0xc)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
} else {
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
if (dig_connector->igp_lane_info & 0x1)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
else if (dig_connector->igp_lane_info & 0x2)
780,35 → 868,25
else if (dig_connector->igp_lane_info & 0x8)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
}
} else {
if (radeon_encoder->pixel_clock > 165000)
args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
ATOM_TRANSMITTER_CONFIG_LINKA_B |
ATOM_TRANSMITTER_CONFIG_LANE_0_7);
else {
if (dig_connector->linkb)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
else
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
}
}
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* Only dig2 encoder can drive LVTMA */
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
break;
}
 
if (radeon_encoder->pixel_clock > 165000)
args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
ATOM_TRANSMITTER_CONFIG_LINKA_B |
ATOM_TRANSMITTER_CONFIG_LANE_0_7);
else {
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
 
if (dig_connector->linkb)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
else
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
}
break;
}
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
 
if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (is_dp)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
}
918,12 → 996,16
if (is_dig) {
switch (mode) {
case DRM_MODE_DPMS_ON:
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
{
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
dp_link_train(encoder, connector);
}
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
break;
}
} else {
1025,13 → 1107,33
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
else
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
} else
} else {
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *dig_connector;
 
connector = radeon_get_connector_for_encoder(encoder);
if (!connector)
return;
radeon_connector = to_radeon_connector(connector);
if (!radeon_connector->con_priv)
return;
dig_connector = radeon_connector->con_priv;
 
/* XXX doesn't really matter which dig encoder we pick as long as it's
* not already in use
*/
if (dig_connector->linkb)
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
else
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
}
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* Only dig2 encoder can drive LVTMA */
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1104,6 → 1206,8
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 
if (radeon_encoder->active_device &
(ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
if (radeon_encoder->enc_priv) {
struct radeon_encoder_atom_dig *dig;
 
1110,6 → 1214,7
dig = radeon_encoder->enc_priv;
dig->dig_block = radeon_crtc->crtc_id;
}
}
radeon_encoder->pixel_clock = adjusted_mode->clock;
 
radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
1134,14 → 1239,14
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* disable the encoder and transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
 
/* setup and enable the encoder and transmitter */
atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
break;
case ENCODER_OBJECT_ID_INTERNAL_DDI:
atombios_ddia_setup(encoder, ATOM_ENABLE);
1354,7 → 1459,6
encoder->possible_crtcs = 0x1;
else
encoder->possible_crtcs = 0x3;
encoder->possible_clones = 0;
 
radeon_encoder->enc_priv = NULL;
 
/drivers/video/drm/radeon/radeon_fence.c
168,37 → 168,6
return signaled;
}
 
int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy)
{
struct radeon_device *rdev;
int ret = 0;
 
rdev = fence->rdev;
 
__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 
while (1) {
if (radeon_fence_signaled(fence))
break;
 
if (time_after_eq(jiffies, fence->timeout)) {
ret = -EBUSY;
break;
}
 
if (lazy)
schedule_timeout(1);
 
if (intr && signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
__set_current_state(TASK_RUNNING);
return ret;
}
 
 
int radeon_fence_wait(struct radeon_fence *fence, bool intr)
{
struct radeon_device *rdev;
216,13 → 185,6
return 0;
}
 
if (rdev->family >= CHIP_R600) {
r = r600_fence_wait(fence, intr, 0);
if (r == -ERESTARTSYS)
return -EBUSY;
return r;
}
 
retry:
cur_jiffies = jiffies;
timeout = HZ / 100;
231,14 → 193,17
}
 
if (intr) {
radeon_irq_kms_sw_irq_get(rdev);
r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
radeon_fence_signaled(fence), timeout);
if (unlikely(r == -ERESTARTSYS)) {
return -EBUSY;
}
radeon_irq_kms_sw_irq_put(rdev);
if (unlikely(r < 0))
return r;
} else {
radeon_irq_kms_sw_irq_get(rdev);
r = wait_event_timeout(rdev->fence_drv.queue,
radeon_fence_signaled(fence), timeout);
radeon_irq_kms_sw_irq_put(rdev);
}
if (unlikely(!radeon_fence_signaled(fence))) {
if (unlikely(r == 0)) {
/drivers/video/drm/radeon/radeon_fixed.h
38,6 → 38,23
#define fixed_init_half(A) { .full = rfixed_const_half((A)) }
#define rfixed_trunc(A) ((A).full >> 12)
 
static inline u32 rfixed_floor(fixed20_12 A)
{
u32 non_frac = rfixed_trunc(A);
 
return rfixed_const(non_frac);
}
 
static inline u32 rfixed_ceil(fixed20_12 A)
{
u32 non_frac = rfixed_trunc(A);
 
if (A.full > rfixed_const(non_frac))
return rfixed_const(non_frac + 1);
else
return rfixed_const(non_frac);
}
 
static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B)
{
u64 tmp = ((u64)A.full << 13);
/drivers/video/drm/radeon/radeon_i2c.c
59,16 → 59,17
}
 
 
void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state)
void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
{
struct radeon_device *rdev = radeon_connector->base.dev->dev_private;
struct radeon_device *rdev = i2c->dev->dev_private;
struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t temp;
struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec;
 
/* RV410 appears to have a bug where the hw i2c in reset
* holds the i2c port in a bad state - switch hw i2c away before
* doing DDC - do this for all r200s/r300s/r400s for safety sake
*/
if (rec->hw_capable) {
if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
if (rec->a_clk_reg == RADEON_GPIO_MONID) {
WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
78,16 → 79,23
R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
}
}
if (lock_state) {
temp = RREG32(rec->a_clk_reg);
temp &= ~(rec->a_clk_mask);
}
 
/* clear the output pin values */
temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
WREG32(rec->a_clk_reg, temp);
 
temp = RREG32(rec->a_data_reg);
temp &= ~(rec->a_data_mask);
temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
WREG32(rec->a_data_reg, temp);
}
 
/* set the pins to input */
temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
WREG32(rec->en_clk_reg, temp);
 
temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
WREG32(rec->en_data_reg, temp);
 
/* mask the gpio pins for software use */
temp = RREG32(rec->mask_clk_reg);
if (lock_state)
temp |= rec->mask_clk_mask;
112,8 → 120,9
struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val;
 
val = RREG32(rec->get_clk_reg);
val &= rec->get_clk_mask;
/* read the value off the pin */
val = RREG32(rec->y_clk_reg);
val &= rec->y_clk_mask;
 
return (val != 0);
}
126,8 → 135,10
struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val;
 
val = RREG32(rec->get_data_reg);
val &= rec->get_data_mask;
/* read the value off the pin */
val = RREG32(rec->y_data_reg);
val &= rec->y_data_mask;
 
return (val != 0);
}
 
138,9 → 149,10
struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val;
 
val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask);
val |= clock ? 0 : rec->put_clk_mask;
WREG32(rec->put_clk_reg, val);
/* set pin direction */
val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
val |= clock ? 0 : rec->en_clk_mask;
WREG32(rec->en_clk_reg, val);
}
 
static void set_data(void *i2c_priv, int data)
150,9 → 162,10
struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val;
 
val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask);
val |= data ? 0 : rec->put_data_mask;
WREG32(rec->put_data_reg, val);
/* set pin direction */
val = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
val |= data ? 0 : rec->en_data_mask;
WREG32(rec->en_data_reg, val);
}
 
struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
166,21 → 179,18
if (i2c == NULL)
return NULL;
 
// i2c->adapter.owner = THIS_MODULE;
i2c->adapter.algo_data = &i2c->algo;
i2c->dev = dev;
i2c->algo.setsda = set_data;
i2c->algo.setscl = set_clock;
i2c->algo.getsda = get_data;
i2c->algo.getscl = get_clock;
i2c->algo.udelay = 20;
i2c->adapter.algo_data = &i2c->algo.bit;
i2c->algo.bit.setsda = set_data;
i2c->algo.bit.setscl = set_clock;
i2c->algo.bit.getsda = get_data;
i2c->algo.bit.getscl = get_clock;
i2c->algo.bit.udelay = 20;
/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
* make this, 2 jiffies is a lot more reliable */
i2c->algo.timeout = 2;
i2c->algo.data = i2c;
i2c->algo.bit.timeout = 2;
i2c->algo.bit.data = i2c;
i2c->rec = *rec;
// i2c_set_adapdata(&i2c->adapter, i2c);
 
ret = i2c_bit_add_bus(&i2c->adapter);
if (ret) {
DRM_INFO("Failed to register i2c %s\n", name);
194,12 → 204,42
 
}
 
struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name)
{
struct radeon_i2c_chan *i2c;
int ret;
 
i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
if (i2c == NULL)
return NULL;
 
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->dev = dev;
i2c->adapter.algo_data = &i2c->algo.dp;
i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
i2c->algo.dp.address = 0;
ret = i2c_dp_aux_add_bus(&i2c->adapter);
if (ret) {
DRM_INFO("Failed to register i2c %s\n", name);
goto out_free;
}
 
return i2c;
out_free:
kfree(i2c);
return NULL;
 
}
 
 
void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
{
if (!i2c)
return;
 
// i2c_del_adapter(&i2c->adapter);
kfree(i2c);
}
 
207,3 → 247,59
{
return NULL;
}
 
void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 *val)
{
u8 out_buf[2];
u8 in_buf[2];
struct i2c_msg msgs[] = {
{
.addr = slave_addr,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
.addr = slave_addr,
.flags = I2C_M_RD,
.len = 1,
.buf = in_buf,
}
};
 
out_buf[0] = addr;
out_buf[1] = 0;
 
if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
*val = in_buf[0];
DRM_DEBUG("val = 0x%02x\n", *val);
} else {
DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
addr, *val);
}
}
 
void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 val)
{
uint8_t out_buf[2];
struct i2c_msg msg = {
.addr = slave_addr,
.flags = 0,
.len = 2,
.buf = out_buf,
};
 
out_buf[0] = addr;
out_buf[1] = val;
 
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
addr, val);
}
 
/drivers/video/drm/radeon/radeon_legacy_crtc.c
30,6 → 30,18
#include "radeon.h"
#include "atom.h"
 
static void radeon_overscan_setup(struct drm_crtc *crtc,
struct drm_display_mode *mode)
{
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0);
WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0);
WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0);
}
 
static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
292,8 → 304,7
uint32_t mask;
 
if (radeon_crtc->crtc_id)
mask = (RADEON_CRTC2_EN |
RADEON_CRTC2_DISP_DIS |
mask = (RADEON_CRTC2_DISP_DIS |
RADEON_CRTC2_VSYNC_DIS |
RADEON_CRTC2_HSYNC_DIS |
RADEON_CRTC2_DISP_REQ_EN_B);
305,7 → 316,7
switch (mode) {
case DRM_MODE_DPMS_ON:
if (radeon_crtc->crtc_id)
WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask);
WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
else {
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
RADEON_CRTC_DISP_REQ_EN_B));
319,7 → 330,7
case DRM_MODE_DPMS_OFF:
// drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
if (radeon_crtc->crtc_id)
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
else {
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
RADEON_CRTC_DISP_REQ_EN_B));
400,6 → 411,7
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_framebuffer *radeon_fb;
struct drm_gem_object *obj;
struct radeon_bo *rbo;
uint64_t base;
uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
uint32_t crtc_pitch, pitch_pixels;
406,8 → 418,14
uint32_t tiling_flags;
int format;
uint32_t gen_cntl_reg, gen_cntl_val;
int r;
 
DRM_DEBUG("\n");
/* no fb bound */
if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
return 0;
}
 
radeon_fb = to_radeon_framebuffer(crtc->fb);
 
431,11 → 449,21
return false;
}
 
/* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj;
// if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) {
// return -EINVAL;
// }
base = rdev->mc.vram_location;
rbo = obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base);
if (unlikely(r != 0)) {
radeon_bo_unreserve(rbo);
return -EINVAL;
}
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
if (tiling_flags & RADEON_TILING_MICRO)
DRM_ERROR("trying to scanout microtiled buffer\n");
 
/* if scanout was in GTT this really wouldn't work */
/* crtc offset is from display base addr not FB location */
451,13 → 479,7
(crtc->fb->bits_per_pixel * 8));
crtc_pitch |= crtc_pitch << 16;
 
// radeon_object_get_tiling_flags(obj->driver_private,
// &tiling_flags, NULL);
tiling_flags = 0;
 
if (tiling_flags & RADEON_TILING_MICRO)
DRM_ERROR("trying to scanout microtiled buffer\n");
 
if (tiling_flags & RADEON_TILING_MACRO) {
if (ASIC_IS_R300(rdev))
crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
532,10 → 554,15
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset);
WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
 
// if (old_fb && old_fb != crtc->fb) {
// radeon_fb = to_radeon_framebuffer(old_fb);
// radeon_gem_object_unpin(radeon_fb->obj);
// }
if (old_fb && old_fb != crtc->fb) {
radeon_fb = to_radeon_framebuffer(old_fb);
rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
}
 
/* Bytes per pixel may have changed */
radeon_bandwidth_update(rdev);
646,12 → 673,8
uint32_t crtc2_gen_cntl;
uint32_t disp2_merge_cntl;
 
/* check to see if TV DAC is enabled for another crtc and keep it enabled */
if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON)
crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
else
crtc2_gen_cntl = 0;
 
/* if TV DAC is enabled for another crtc and keep it enabled */
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080;
crtc2_gen_cntl |= ((format << 8)
| RADEON_CRTC2_VSYNC_DIS
| RADEON_CRTC2_HSYNC_DIS
680,7 → 703,8
uint32_t crtc_ext_cntl;
uint32_t disp_merge_cntl;
 
crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000;
crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN
| (format << 8)
| RADEON_CRTC_DISP_REQ_EN_B
| ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
783,6 → 807,7
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
if (!rdev->is_atom_bios) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
if (lvds) {
794,6 → 819,7
use_bios_divs = true;
}
}
}
pll_flags |= RADEON_PLL_USE_REF_DIV;
}
}
1031,6 → 1057,7
radeon_crtc_set_base(crtc, x, y, old_fb);
radeon_set_crtc_timing(crtc, adjusted_mode);
radeon_set_pll(crtc, adjusted_mode);
radeon_overscan_setup(crtc, adjusted_mode);
if (radeon_crtc->crtc_id == 0) {
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
} else {
1046,13 → 1073,30
 
static void radeon_crtc_prepare(struct drm_crtc *crtc)
{
radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
struct drm_device *dev = crtc->dev;
struct drm_crtc *crtci;
 
/*
* The hardware wedges sometimes if you reconfigure one CRTC
* whilst another is running (see fdo bug #24611).
*/
list_for_each_entry(crtci, &dev->mode_config.crtc_list, head)
radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF);
}
 
static void radeon_crtc_commit(struct drm_crtc *crtc)
{
radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
struct drm_device *dev = crtc->dev;
struct drm_crtc *crtci;
 
/*
* Reenable the CRTCs that should be running.
*/
list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) {
if (crtci->enabled)
radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
}
}
 
static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.dpms = radeon_crtc_dpms,
/drivers/video/drm/radeon/radeon_legacy_encoders.c
136,7 → 136,14
lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
 
lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
if ((!rdev->is_atom_bios)) {
if (rdev->is_atom_bios) {
/* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl
* need to call that on resume to set up the reg properly.
*/
radeon_encoder->pixel_clock = adjusted_mode->clock;
atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
} else {
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
if (lvds) {
DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
147,8 → 154,7
(lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
} else
lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
} else
lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
}
lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
lvds_gen_cntl &= ~(RADEON_LVDS_ON |
RADEON_LVDS_BLON |
184,7 → 190,7
radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
}
 
static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
194,8 → 200,15
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
 
if (radeon_encoder->rmx_type != RMX_OFF)
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
/* get the native mode for LVDS */
if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
int mode_id = adjusted_mode->base.id;
*adjusted_mode = *native_mode;
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
adjusted_mode->base.id = mode_id;
}
 
return true;
}
202,7 → 215,7
 
static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
.dpms = radeon_legacy_lvds_dpms,
.mode_fixup = radeon_legacy_lvds_mode_fixup,
.mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_lvds_prepare,
.mode_set = radeon_legacy_lvds_mode_set,
.commit = radeon_legacy_lvds_commit,
214,17 → 227,6
.destroy = radeon_enc_destroy,
};
 
static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* set the active encoder to connector routing */
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
 
return true;
}
 
static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
410,7 → 412,7
 
static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = {
.dpms = radeon_legacy_primary_dac_dpms,
.mode_fixup = radeon_legacy_primary_dac_mode_fixup,
.mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_primary_dac_prepare,
.mode_set = radeon_legacy_primary_dac_mode_set,
.commit = radeon_legacy_primary_dac_commit,
423,16 → 425,6
.destroy = radeon_enc_destroy,
};
 
static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
 
drm_mode_set_crtcinfo(adjusted_mode, 0);
 
return true;
}
 
static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
584,7 → 576,7
 
static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = {
.dpms = radeon_legacy_tmds_int_dpms,
.mode_fixup = radeon_legacy_tmds_int_mode_fixup,
.mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_tmds_int_prepare,
.mode_set = radeon_legacy_tmds_int_mode_set,
.commit = radeon_legacy_tmds_int_commit,
596,17 → 588,6
.destroy = radeon_enc_destroy,
};
 
static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* set the active encoder to connector routing */
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
 
return true;
}
 
static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
697,6 → 678,8
/*if (mode->clock > 165000)
fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
}
if (!radeon_combios_external_tmds_setup(encoder))
radeon_external_tmds_setup(encoder);
}
 
if (radeon_crtc->crtc_id == 0) {
724,9 → 707,22
radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
}
 
static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
if (tmds) {
if (tmds->i2c_bus)
radeon_i2c_destroy(tmds->i2c_bus);
}
kfree(radeon_encoder->enc_priv);
drm_encoder_cleanup(encoder);
kfree(radeon_encoder);
}
 
static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
.dpms = radeon_legacy_tmds_ext_dpms,
.mode_fixup = radeon_legacy_tmds_ext_mode_fixup,
.mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_tmds_ext_prepare,
.mode_set = radeon_legacy_tmds_ext_mode_set,
.commit = radeon_legacy_tmds_ext_commit,
735,20 → 731,9
 
 
static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
.destroy = radeon_enc_destroy,
.destroy = radeon_ext_tmds_enc_destroy,
};
 
static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* set the active encoder to connector routing */
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
 
return true;
}
 
static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
1265,7 → 1250,7
 
static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = {
.dpms = radeon_legacy_tv_dac_dpms,
.mode_fixup = radeon_legacy_tv_dac_mode_fixup,
.mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_tv_dac_prepare,
.mode_set = radeon_legacy_tv_dac_mode_set,
.commit = radeon_legacy_tv_dac_commit,
1302,6 → 1287,29
return tmds;
}
 
static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder_ext_tmds *tmds = NULL;
bool ret;
 
if (rdev->is_atom_bios)
return NULL;
 
tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL);
 
if (!tmds)
return NULL;
 
ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds);
 
if (ret == false)
radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds);
 
return tmds;
}
 
void
radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{
1329,7 → 1337,6
encoder->possible_crtcs = 0x1;
else
encoder->possible_crtcs = 0x3;
encoder->possible_clones = 0;
 
radeon_encoder->enc_priv = NULL;
 
1373,7 → 1380,7
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
if (!rdev->is_atom_bios)
radeon_combios_get_ext_tmds_info(radeon_encoder);
radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder);
break;
}
}
/drivers/video/drm/radeon/radeon_mode.h
33,6 → 33,7
#include <drm_crtc.h>
#include <drm_mode.h>
#include <drm_edid.h>
#include <drm_dp_helper.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
89,24 → 90,45
TV_STD_PAL_CN,
};
 
/* radeon gpio-based i2c
* 1. "mask" reg and bits
* grabs the gpio pins for software use
* 0=not held 1=held
* 2. "a" reg and bits
* output pin value
* 0=low 1=high
* 3. "en" reg and bits
* sets the pin direction
* 0=input 1=output
* 4. "y" reg and bits
* input pin value
* 0=low 1=high
*/
struct radeon_i2c_bus_rec {
bool valid;
/* id used by atom */
uint8_t i2c_id;
/* can be used with hw i2c engine */
bool hw_capable;
/* uses multi-media i2c engine */
bool mm_i2c;
/* regs and bits */
uint32_t mask_clk_reg;
uint32_t mask_data_reg;
uint32_t a_clk_reg;
uint32_t a_data_reg;
uint32_t put_clk_reg;
uint32_t put_data_reg;
uint32_t get_clk_reg;
uint32_t get_data_reg;
uint32_t en_clk_reg;
uint32_t en_data_reg;
uint32_t y_clk_reg;
uint32_t y_data_reg;
uint32_t mask_clk_mask;
uint32_t mask_data_mask;
uint32_t put_clk_mask;
uint32_t put_data_mask;
uint32_t get_clk_mask;
uint32_t get_data_mask;
uint32_t a_clk_mask;
uint32_t a_data_mask;
uint32_t en_clk_mask;
uint32_t en_data_mask;
uint32_t y_clk_mask;
uint32_t y_data_mask;
};
 
struct radeon_tmds_pll {
150,9 → 172,12
};
 
struct radeon_i2c_chan {
struct i2c_adapter adapter;
struct drm_device *dev;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo;
union {
struct i2c_algo_dp_aux_data dp;
struct i2c_algo_bit_data bit;
} algo;
struct radeon_i2c_bus_rec rec;
};
 
170,6 → 195,11
CT_EMAC,
};
 
enum radeon_dvo_chip {
DVO_SIL164,
DVO_SIL1178,
};
 
struct radeon_mode_info {
struct atom_context *atom_context;
struct card_info *atom_card_info;
209,7 → 239,7
bool enabled;
bool can_tile;
uint32_t crtc_offset;
// struct drm_gem_object *cursor_bo;
struct drm_gem_object *cursor_bo;
uint64_t cursor_addr;
int cursor_width;
int cursor_height;
261,6 → 291,13
struct radeon_tmds_pll tmds_pll[4];
};
 
struct radeon_encoder_ext_tmds {
/* tmds over dvo */
struct radeon_i2c_chan *i2c_bus;
uint8_t slave_addr;
enum radeon_dvo_chip dvo_chip;
};
 
/* spread spectrum */
struct radeon_atom_ss {
uint16_t percentage;
302,8 → 339,37
struct radeon_connector_atom_dig {
uint32_t igp_lane_info;
bool linkb;
/* displayport */
struct radeon_i2c_chan *dp_i2c_bus;
u8 dpcd[8];
u8 dp_sink_type;
int dp_clock;
int dp_lane_count;
};
 
struct radeon_gpio_rec {
bool valid;
u8 id;
u32 reg;
u32 mask;
};
 
enum radeon_hpd_id {
RADEON_HPD_NONE = 0,
RADEON_HPD_1,
RADEON_HPD_2,
RADEON_HPD_3,
RADEON_HPD_4,
RADEON_HPD_5,
RADEON_HPD_6,
};
 
struct radeon_hpd {
enum radeon_hpd_id hpd;
u8 plugged_state;
struct radeon_gpio_rec gpio;
};
 
struct radeon_connector {
struct drm_connector base;
uint32_t connector_id;
318,6 → 384,7
void *con_priv;
bool dac_load_detect;
uint16_t connector_object_id;
struct radeon_hpd hpd;
};
 
struct radeon_framebuffer {
325,10 → 392,37
struct drm_gem_object *obj;
};
 
extern void radeon_connector_hotplug(struct drm_connector *connector);
extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
struct drm_display_mode *mode);
extern void radeon_dp_set_link_config(struct drm_connector *connector,
struct drm_display_mode *mode);
extern void dp_link_train(struct drm_encoder *encoder,
struct drm_connector *connector);
extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num,
uint8_t lane_set);
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
uint8_t write_byte, uint8_t *read_byte);
 
extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name);
extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name);
extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 *val);
extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c,
u8 slave_addr,
u8 addr,
u8 val);
extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
343,6 → 437,17
uint32_t *post_div_p,
int flags);
 
extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
uint64_t freq,
uint32_t *dot_clock_p,
uint32_t *fb_div_p,
uint32_t *frac_fb_div_p,
uint32_t *ref_div_p,
uint32_t *post_div_p,
int flags);
 
extern void radeon_setup_encoder_clones(struct drm_device *dev);
 
struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
349,6 → 454,7
struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
378,12 → 484,16
extern bool radeon_combios_get_clock_info(struct drm_device *dev);
extern struct radeon_encoder_atom_dig *
radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds);
extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds);
extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds);
extern struct radeon_encoder_primary_dac *
radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_tv_dac *
395,6 → 505,8
radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_primary_dac *
radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder);
extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder);
extern void radeon_external_tmds_setup(struct drm_encoder *encoder);
extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
426,7 → 538,7
struct radeon_crtc *radeon_crtc);
void radeon_legacy_init_crtc(struct drm_device *dev,
struct radeon_crtc *radeon_crtc);
void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state);
extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state);
 
void radeon_get_clock_info(struct drm_device *dev);
 
433,9 → 545,6
extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev);
extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev);
 
void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void radeon_enc_destroy(struct drm_encoder *encoder);
void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
void radeon_combios_asic_init(struct drm_device *dev);
/drivers/video/drm/radeon/radeon_object.h
28,328 → 28,152
#ifndef __RADEON_OBJECT_H__
#define __RADEON_OBJECT_H__
 
//#include <ttm/ttm_bo_api.h>
//#include <ttm/ttm_bo_driver.h>
//#include <ttm/ttm_placement.h>
//#include <ttm/ttm_module.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
 
/*
* TTM.
*/
//struct radeon_mman {
// struct ttm_global_reference mem_global_ref;
// bool mem_global_referenced;
// struct ttm_bo_device bdev;
//};
 
 
#define TTM_PL_SYSTEM 0
#define TTM_PL_TT 1
#define TTM_PL_VRAM 2
#define TTM_PL_PRIV0 3
#define TTM_PL_PRIV1 4
#define TTM_PL_PRIV2 5
#define TTM_PL_PRIV3 6
#define TTM_PL_PRIV4 7
#define TTM_PL_PRIV5 8
#define TTM_PL_SWAPPED 15
 
#define TTM_PL_FLAG_SYSTEM (1 << TTM_PL_SYSTEM)
#define TTM_PL_FLAG_TT (1 << TTM_PL_TT)
#define TTM_PL_FLAG_VRAM (1 << TTM_PL_VRAM)
#define TTM_PL_FLAG_PRIV0 (1 << TTM_PL_PRIV0)
#define TTM_PL_FLAG_PRIV1 (1 << TTM_PL_PRIV1)
#define TTM_PL_FLAG_PRIV2 (1 << TTM_PL_PRIV2)
#define TTM_PL_FLAG_PRIV3 (1 << TTM_PL_PRIV3)
#define TTM_PL_FLAG_PRIV4 (1 << TTM_PL_PRIV4)
#define TTM_PL_FLAG_PRIV5 (1 << TTM_PL_PRIV5)
#define TTM_PL_FLAG_SWAPPED (1 << TTM_PL_SWAPPED)
#define TTM_PL_MASK_MEM 0x0000FFFF
 
 
struct ttm_mem_type_manager {
 
/*
* No protection. Constant from start.
*/
 
bool has_type;
bool use_type;
uint32_t flags;
unsigned long gpu_offset;
unsigned long io_offset;
unsigned long io_size;
void *io_addr;
uint64_t size;
uint32_t available_caching;
uint32_t default_caching;
 
/*
* Protected by the bdev->lru_lock.
* TODO: Consider one lru_lock per ttm_mem_type_manager.
* Plays ill with list removal, though.
*/
 
struct drm_mm manager;
struct list_head lru;
};
 
struct ttm_bo_driver {
const uint32_t *mem_type_prio;
const uint32_t *mem_busy_prio;
uint32_t num_mem_type_prio;
uint32_t num_mem_busy_prio;
 
/**
* struct ttm_bo_driver member create_ttm_backend_entry
* radeon_mem_type_to_domain - return domain corresponding to mem_type
* @mem_type: ttm memory type
*
* @bdev: The buffer object device.
*
* Create a driver specific struct ttm_backend.
* Returns corresponding domain of the ttm mem_type
*/
static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
{
switch (mem_type) {
case TTM_PL_VRAM:
return RADEON_GEM_DOMAIN_VRAM;
case TTM_PL_TT:
return RADEON_GEM_DOMAIN_GTT;
case TTM_PL_SYSTEM:
return RADEON_GEM_DOMAIN_CPU;
default:
break;
}
return 0;
}
 
// struct ttm_backend *(*create_ttm_backend_entry)(struct ttm_bo_device *bdev);
 
/**
* struct ttm_bo_driver member invalidate_caches
* radeon_bo_reserve - reserve bo
* @bo: bo structure
* @no_wait: don't sleep while trying to reserve (return -EBUSY)
*
* @bdev: the buffer object device.
* @flags: new placement of the rebound buffer object.
*
* A previosly evicted buffer has been rebound in a
* potentially new location. Tell the driver that it might
* consider invalidating read (texture) caches on the next command
* submission as a consequence.
* Returns:
* -EBUSY: buffer is busy and @no_wait is true
* -ERESTART: A wait for the buffer to become unreserved was interrupted by
* a signal. Release all buffer reservations and return to user-space.
*/
static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
{
int r;
 
// int (*invalidate_caches) (struct ttm_bo_device *bdev, uint32_t flags);
// int (*init_mem_type) (struct ttm_bo_device *bdev, uint32_t type,
// struct ttm_mem_type_manager *man);
/**
* struct ttm_bo_driver member evict_flags:
*
* @bo: the buffer object to be evicted
*
* Return the bo flags for a buffer which is not mapped to the hardware.
* These will be placed in proposed_flags so that when the move is
* finished, they'll end up in bo->mem.flags
*/
retry:
r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
if (unlikely(r != 0)) {
if (r == -ERESTART)
goto retry;
dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
return r;
}
return 0;
}
 
// uint32_t(*evict_flags) (struct ttm_buffer_object *bo);
/**
* struct ttm_bo_driver member move:
*
* @bo: the buffer to move
* @evict: whether this motion is evicting the buffer from
* the graphics address space
* @interruptible: Use interruptible sleeps if possible when sleeping.
* @no_wait: whether this should give up and return -EBUSY
* if this move would require sleeping
* @new_mem: the new memory region receiving the buffer
*
* Move a buffer between two memory regions.
*/
// int (*move) (struct ttm_buffer_object *bo,
// bool evict, bool interruptible,
// bool no_wait, struct ttm_mem_reg *new_mem);
static inline void radeon_bo_unreserve(struct radeon_bo *bo)
{
ttm_bo_unreserve(&bo->tbo);
}
 
/**
* struct ttm_bo_driver_member verify_access
* radeon_bo_gpu_offset - return GPU offset of bo
* @bo: radeon object for which we query the offset
*
* @bo: Pointer to a buffer object.
* @filp: Pointer to a struct file trying to access the object.
* Returns current GPU offset of the object.
*
* Called from the map / write / read methods to verify that the
* caller is permitted to access the buffer object.
* This member may be set to NULL, which will refuse this kind of
* access for all buffer objects.
* This function should return 0 if access is granted, -EPERM otherwise.
* Note: object should either be pinned or reserved when calling this
* function, it might be usefull to add check for this for debugging.
*/
// int (*verify_access) (struct ttm_buffer_object *bo,
// struct file *filp);
static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo)
{
return bo->tbo.offset;
}
 
/**
* In case a driver writer dislikes the TTM fence objects,
* the driver writer can replace those with sync objects of
* his / her own. If it turns out that no driver writer is
* using these. I suggest we remove these hooks and plug in
* fences directly. The bo driver needs the following functionality:
* See the corresponding functions in the fence object API
* documentation.
*/
static inline unsigned long radeon_bo_size(struct radeon_bo *bo)
{
return bo->tbo.num_pages << PAGE_SHIFT;
}
 
// bool (*sync_obj_signaled) (void *sync_obj, void *sync_arg);
// int (*sync_obj_wait) (void *sync_obj, void *sync_arg,
// bool lazy, bool interruptible);
// int (*sync_obj_flush) (void *sync_obj, void *sync_arg);
// void (*sync_obj_unref) (void **sync_obj);
// void *(*sync_obj_ref) (void *sync_obj);
};
static inline bool radeon_bo_is_reserved(struct radeon_bo *bo)
{
return !!atomic_read(&bo->tbo.reserved);
}
 
#define TTM_NUM_MEM_TYPES 8
 
 
struct ttm_bo_device {
 
/*
* Constant after bo device init / atomic.
*/
 
// struct ttm_mem_global *mem_glob;
struct ttm_bo_driver *driver;
// struct page *dummy_read_page;
// struct ttm_mem_shrink shrink;
 
size_t ttm_bo_extra_size;
size_t ttm_bo_size;
 
// rwlock_t vm_lock;
/*
* Protected by the vm lock.
*/
struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES];
// struct rb_root addr_space_rb;
struct drm_mm addr_space_mm;
 
/*
* Might want to change this to one lock per manager.
*/
// spinlock_t lru_lock;
/*
* Protected by the lru lock.
*/
struct list_head ddestroy;
struct list_head swap_lru;
 
/*
* Protected by load / firstopen / lastclose /unload sync.
*/
 
bool nice_mode;
// struct address_space *dev_mapping;
 
/*
* Internal protection.
*/
 
// struct delayed_work wq;
};
 
struct ttm_mem_reg {
struct drm_mm_node *mm_node;
unsigned long size;
unsigned long num_pages;
uint32_t page_alignment;
uint32_t mem_type;
uint32_t placement;
};
 
enum ttm_bo_type {
ttm_bo_type_device,
ttm_bo_type_user,
ttm_bo_type_kernel
};
 
struct ttm_buffer_object {
/**
* Members constant at init.
* radeon_bo_mmap_offset - return mmap offset of bo
* @bo: radeon object for which we query the offset
*
* Returns mmap offset of the object.
*
* Note: addr_space_offset is constant after ttm bo init thus isn't protected
* by any lock.
*/
static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo)
{
return bo->tbo.addr_space_offset;
}
 
struct ttm_bo_device *bdev;
unsigned long buffer_start;
enum ttm_bo_type type;
void (*destroy) (struct ttm_buffer_object *);
unsigned long num_pages;
uint64_t addr_space_offset;
size_t acc_size;
 
/**
* Members not needing protection.
*/
 
// struct kref kref;
// struct kref list_kref;
// wait_queue_head_t event_queue;
// spinlock_t lock;
 
/**
* Members protected by the bo::reserved lock.
*/
 
uint32_t proposed_placement;
struct ttm_mem_reg mem;
// struct file *persistant_swap_storage;
// struct ttm_tt *ttm;
bool evicted;
 
/**
* Members protected by the bo::reserved lock only when written to.
*/
 
// atomic_t cpu_writers;
 
/**
* Members protected by the bdev::lru_lock.
*/
 
struct list_head lru;
struct list_head ddestroy;
struct list_head swap;
uint32_t val_seq;
bool seq_valid;
 
/**
* Members protected by the bdev::lru_lock
* only when written to.
*/
 
// atomic_t reserved;
 
 
/**
* Members protected by the bo::lock
*/
 
void *sync_obj_arg;
void *sync_obj;
unsigned long priv_flags;
 
/**
* Members protected by the bdev::vm_lock
*/
 
// struct rb_node vm_rb;
struct drm_mm_node *vm_node;
 
 
/**
* Special members that are protected by the reserve lock
* and the bo::lock when written to. Can be read with
* either of these locks held.
*/
 
unsigned long offset;
uint32_t cur_placement;
};
 
struct radeon_object
static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
bool no_wait)
{
struct ttm_buffer_object tobj;
struct list_head list;
struct radeon_device *rdev;
struct drm_gem_object *gobj;
// struct ttm_bo_kmap_obj kmap;
int r;
 
unsigned pin_count;
uint64_t gpu_addr;
void *kptr;
bool is_iomem;
retry:
r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
if (unlikely(r != 0)) {
if (r == -ERESTART)
goto retry;
dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);
return r;
}
spin_lock(&bo->tbo.lock);
if (mem_type)
*mem_type = bo->tbo.mem.mem_type;
if (bo->tbo.sync_obj)
r = ttm_bo_wait(&bo->tbo, true, true, no_wait);
spin_unlock(&bo->tbo.lock);
ttm_bo_unreserve(&bo->tbo);
if (unlikely(r == -ERESTART))
goto retry;
return r;
}
 
struct drm_mm_node *mm_node;
u32_t vm_addr;
u32_t cpu_addr;
u32_t flags;
};
 
 
extern int radeon_bo_create(struct radeon_device *rdev,
struct drm_gem_object *gobj, unsigned long size,
bool kernel, u32 domain,
struct radeon_bo **bo_ptr);
extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
extern void radeon_bo_kunmap(struct radeon_bo *bo);
extern void radeon_bo_unref(struct radeon_bo **bo);
extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
extern int radeon_bo_unpin(struct radeon_bo *bo);
extern int radeon_bo_evict_vram(struct radeon_device *rdev);
extern void radeon_bo_force_delete(struct radeon_device *rdev);
extern int radeon_bo_init(struct radeon_device *rdev);
extern void radeon_bo_fini(struct radeon_device *rdev);
extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
struct list_head *head);
extern int radeon_bo_list_reserve(struct list_head *head);
extern void radeon_bo_list_unreserve(struct list_head *head);
extern int radeon_bo_list_validate(struct list_head *head, void *fence);
extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence);
extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
struct vm_area_struct *vma);
extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
u32 tiling_flags, u32 pitch);
extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
u32 *tiling_flags, u32 *pitch);
extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
bool force_drop);
extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
struct ttm_mem_reg *mem);
extern void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
#endif
/drivers/video/drm/radeon/radeon_pm.c
27,7 → 27,7
int radeon_pm_init(struct radeon_device *rdev)
{
if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for CP !\n");
DRM_ERROR("Failed to register debugfs file for PM!\n");
}
 
return 0;
44,8 → 44,8
struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private;
 
seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev));
seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev));
seq_printf(m, "engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
seq_printf(m, "memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
 
return 0;
}
/drivers/video/drm/radeon/radeon_reg.h
887,6 → 887,7
# define RADEON_FP_PANEL_FORMAT (1 << 3)
# define RADEON_FP_EN_TMDS (1 << 7)
# define RADEON_FP_DETECT_SENSE (1 << 8)
# define RADEON_FP_DETECT_INT_POL (1 << 9)
# define R200_FP_SOURCE_SEL_MASK (3 << 10)
# define R200_FP_SOURCE_SEL_CRTC1 (0 << 10)
# define R200_FP_SOURCE_SEL_CRTC2 (1 << 10)
894,6 → 895,7
# define R200_FP_SOURCE_SEL_TRANS (3 << 10)
# define RADEON_FP_SEL_CRTC1 (0 << 13)
# define RADEON_FP_SEL_CRTC2 (1 << 13)
# define R300_HPD_SEL(x) ((x) << 13)
# define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15)
# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
# define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17)
909,6 → 911,7
# define RADEON_FP2_ON (1 << 2)
# define RADEON_FP2_PANEL_FORMAT (1 << 3)
# define RADEON_FP2_DETECT_SENSE (1 << 8)
# define RADEON_FP2_DETECT_INT_POL (1 << 9)
# define R200_FP2_SOURCE_SEL_MASK (3 << 10)
# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10)
# define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10)
988,14 → 991,20
 
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
# define RADEON_FP_DETECT_MASK (1 << 4)
# define RADEON_CRTC2_VBLANK_MASK (1 << 9)
# define RADEON_FP2_DETECT_MASK (1 << 10)
# define RADEON_SW_INT_ENABLE (1 << 25)
#define RADEON_GEN_INT_STATUS 0x0044
# define AVIVO_DISPLAY_INT_STATUS (1 << 0)
# define RADEON_CRTC_VBLANK_STAT (1 << 0)
# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0)
# define RADEON_FP_DETECT_STAT (1 << 4)
# define RADEON_FP_DETECT_STAT_ACK (1 << 4)
# define RADEON_CRTC2_VBLANK_STAT (1 << 9)
# define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9)
# define RADEON_FP2_DETECT_STAT (1 << 10)
# define RADEON_FP2_DETECT_STAT_ACK (1 << 10)
# define RADEON_SW_INT_FIRE (1 << 26)
# define RADEON_SW_INT_TEST (1 << 25)
# define RADEON_SW_INT_TEST_ACK (1 << 25)
1062,9 → 1071,14
#define RADEON_I2C_RECEIVE (1<<10)
#define RADEON_I2C_ABORT (1<<11)
#define RADEON_I2C_GO (1<<12)
#define RADEON_I2C_PRESCALE_SHIFT 16
#define RADEON_I2C_CNTL_1 0x0094
#define RADEON_I2C_DATA_COUNT_SHIFT 0
#define RADEON_I2C_ADDR_COUNT_SHIFT 4
#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8
#define RADEON_I2C_SEL (1<<16)
#define RADEON_I2C_EN (1<<17)
#define RADEON_I2C_TIME_LIMIT_SHIFT 24
#define RADEON_I2C_DATA 0x0098
 
#define RADEON_DVI_I2C_CNTL_0 0x02e0
1072,7 → 1086,7
# define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */
# define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */
# define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */
#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */
#define RADEON_DVI_I2C_CNTL_1 0x02e4
#define RADEON_DVI_I2C_DATA 0x02e8
 
#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */
1143,15 → 1157,16
# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14)
# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15)
#define RADEON_LCD_GPIO_MASK 0x01a0
#define RADEON_GPIOPAD_EN 0x01a0
#define RADEON_LCD_GPIO_Y_REG 0x01a4
#define RADEON_MDGPIO_A_REG 0x01ac
#define RADEON_MDGPIO_EN_REG 0x01b0
#define RADEON_MDGPIO_MASK 0x0198
 
#define RADEON_GPIOPAD_MASK 0x0198
#define RADEON_GPIOPAD_A 0x019c
#define RADEON_MDGPIO_Y_REG 0x01b4
#define RADEON_GPIOPAD_EN 0x01a0
#define RADEON_GPIOPAD_Y 0x01a4
#define RADEON_MDGPIO_MASK 0x01a8
#define RADEON_MDGPIO_A 0x01ac
#define RADEON_MDGPIO_EN 0x01b0
#define RADEON_MDGPIO_Y 0x01b4
 
#define RADEON_MEM_ADDR_CONFIG 0x0148
#define RADEON_MEM_BASE 0x0f10 /* PCI */
#define RADEON_MEM_CNTL 0x0140
1360,6 → 1375,9
#define RADEON_OVR_CLR 0x0230
#define RADEON_OVR_WID_LEFT_RIGHT 0x0234
#define RADEON_OVR_WID_TOP_BOTTOM 0x0238
#define RADEON_OVR2_CLR 0x0330
#define RADEON_OVR2_WID_LEFT_RIGHT 0x0334
#define RADEON_OVR2_WID_TOP_BOTTOM 0x0338
 
/* first capture unit */
 
/drivers/video/drm/radeon/rs400.c
352,7 → 352,7
u32 tmp;
 
/* Setup GPU memory space */
tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
tmp = RREG32(R_00015C_NB_TOM);
rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
rdev->mc.gtt_location = 0xFFFFFFFFUL;
r = radeon_mc_setup(rdev);
387,6 → 387,7
r300_clock_startup(rdev);
/* Initialize GPU configuration (# pipes, ...) */
rs400_gpu_init(rdev);
r100_enable_bm(rdev);
/* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */
r = rs400_gart_enable(rdev);
393,7 → 394,6
if (r)
return r;
/* Enable IRQ */
// rdev->irq.sw_int = true;
// r100_irq_set(rdev);
/* 1M ring buffer */
// r = r100_cp_init(rdev, 1024 * 1024);
447,10 → 447,9
RREG32(R_0007C0_CP_STAT));
}
/* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
radeon_combios_asic_init(rdev->ddev);
}
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
 
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
/* Get vram informations */
467,7 → 466,7
// if (r)
// return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
r = rs400_gart_init(rdev);
/drivers/video/drm/radeon/rs600.c
45,6 → 45,122
void rs600_gpu_init(struct radeon_device *rdev);
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
 
int rs600_mc_init(struct radeon_device *rdev)
{
/* read back the MC value from the hw */
int r;
u32 tmp;
 
/* Setup GPU memory space */
tmp = RREG32_MC(R_000004_MC_FB_LOCATION);
rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
rdev->mc.gtt_location = 0xffffffffUL;
r = radeon_mc_setup(rdev);
if (r)
return r;
return 0;
}
 
/* hpd for digital panel detect/disconnect */
bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
{
u32 tmp;
bool connected = false;
 
switch (hpd) {
case RADEON_HPD_1:
tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS);
if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp))
connected = true;
break;
case RADEON_HPD_2:
tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS);
if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp))
connected = true;
break;
default:
break;
}
return connected;
}
 
void rs600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd)
{
u32 tmp;
bool connected = rs600_hpd_sense(rdev, hpd);
 
switch (hpd) {
case RADEON_HPD_1:
tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL);
if (connected)
tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1);
else
tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1);
WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
break;
case RADEON_HPD_2:
tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL);
if (connected)
tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1);
else
tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1);
WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
break;
default:
break;
}
}
 
void rs600_hpd_init(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_connector *connector;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL,
S_007D00_DC_HOT_PLUG_DETECT1_EN(1));
rdev->irq.hpd[0] = true;
break;
case RADEON_HPD_2:
WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
S_007D10_DC_HOT_PLUG_DETECT2_EN(1));
rdev->irq.hpd[1] = true;
break;
default:
break;
}
}
rs600_irq_set(rdev);
}
 
void rs600_hpd_fini(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
struct drm_connector *connector;
 
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL,
S_007D00_DC_HOT_PLUG_DETECT1_EN(0));
rdev->irq.hpd[0] = false;
break;
case RADEON_HPD_2:
WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
S_007D10_DC_HOT_PLUG_DETECT2_EN(0));
rdev->irq.hpd[1] = false;
break;
default:
break;
}
}
}
 
/*
* GART.
*/
102,38 → 218,38
WREG32_MC(R_000100_MC_PT0_CNTL,
(S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
 
for (i = 0; i < 19; i++) {
WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i,
S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
S_00016C_SYSTEM_ACCESS_MODE_MASK(
V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) |
V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) |
S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) |
S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) |
V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) |
S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) |
S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1));
S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3));
}
 
/* System context map to GART space */
WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start);
WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end);
 
/* enable first context */
WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL,
S_000102_ENABLE_PAGE_TABLE(1) |
S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
 
/* disable all other contexts */
for (i = 1; i < 8; i++) {
for (i = 1; i < 8; i++)
WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0);
}
 
/* setup the page table */
WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
rdev->gart.table_addr);
WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
 
/* System context maps to VRAM space */
WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start);
WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end);
 
/* enable page tables */
tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1)));
146,7 → 262,8
 
void rs600_gart_disable(struct radeon_device *rdev)
{
uint32_t tmp;
u32 tmp;
int r;
 
/* FIXME: disable out of gart access */
WREG32_MC(R_000100_MC_PT0_CNTL, 0);
185,12 → 302,42
return 0;
}
 
int rs600_irq_set(struct radeon_device *rdev)
{
uint32_t tmp = 0;
uint32_t mode_int = 0;
u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) &
~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1);
u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) &
~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
 
if (rdev->irq.sw_int) {
tmp |= S_000040_SW_INT_EN(1);
}
if (rdev->irq.crtc_vblank_int[0]) {
mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1);
}
if (rdev->irq.crtc_vblank_int[1]) {
mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1);
}
if (rdev->irq.hpd[0]) {
hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1);
}
if (rdev->irq.hpd[1]) {
hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
}
WREG32(R_000040_GEN_INT_CNTL, tmp);
WREG32(R_006540_DxMODE_INT_MASK, mode_int);
WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
return 0;
}
 
static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int)
{
uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS);
uint32_t irq_mask = ~C_000044_SW_INT;
u32 tmp;
 
if (G_000044_DISPLAY_INT_STAT(irqs)) {
*r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS);
202,6 → 349,16
WREG32(R_006D34_D2MODE_VBLANK_STATUS,
S_006D34_D2MODE_VBLANK_ACK(1));
}
if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) {
tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL);
tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1);
WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
}
if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) {
tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL);
tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1);
WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
}
} else {
*r500_disp_int = 0;
}
246,9 → 403,7
 
void rs600_gpu_init(struct radeon_device *rdev)
{
/* FIXME: HDP same place on rs600 ? */
r100_hdp_reset(rdev);
/* FIXME: is this correct ? */
r420_pipes_init(rdev);
/* Wait for mc idle */
if (rs600_mc_wait_for_idle(rdev))
257,9 → 412,20
 
void rs600_vram_info(struct radeon_device *rdev)
{
/* FIXME: to do or is these values sane ? */
rdev->mc.vram_is_ddr = true;
rdev->mc.vram_width = 128;
 
rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
 
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
 
if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
rdev->mc.mc_vram_size = rdev->mc.aper_size;
 
if (rdev->mc.real_vram_size > rdev->mc.aper_size)
rdev->mc.real_vram_size = rdev->mc.aper_size;
}
 
void rs600_bandwidth_update(struct radeon_device *rdev)
333,7 → 499,6
if (r)
return r;
/* Enable IRQ */
// rdev->irq.sw_int = true;
// rs600_irq_set(rdev);
/* 1M ring buffer */
// r = r100_cp_init(rdev, 1024 * 1024);
385,10 → 550,9
RREG32(R_0007C0_CP_STAT));
}
/* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
atom_asic_init(rdev->mode_info.atom_context);
}
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
 
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
/* Initialize power management */
396,7 → 560,7
/* Get vram informations */
rs600_vram_info(rdev);
/* Initialize memory controller (also test AGP) */
r = r420_mc_init(rdev);
r = rs600_mc_init(rdev);
if (r)
return r;
rs600_debugfs(rdev);
408,7 → 572,7
// if (r)
// return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
r = rs600_gart_init(rdev);
/drivers/video/drm/radeon/rs600d.h
30,27 → 30,12
 
/* Registers */
#define R_000040_GEN_INT_CNTL 0x000040
#define S_000040_DISPLAY_INT_STATUS(x) (((x) & 0x1) << 0)
#define G_000040_DISPLAY_INT_STATUS(x) (((x) >> 0) & 0x1)
#define C_000040_DISPLAY_INT_STATUS 0xFFFFFFFE
#define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12)
#define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1)
#define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF
#define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6)
#define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1)
#define C_000040_CRTC2_VSYNC 0xFFFFFFBF
#define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7)
#define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1)
#define C_000040_SNAPSHOT2 0xFFFFFF7F
#define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9)
#define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1)
#define C_000040_CRTC2_VBLANK 0xFFFFFDFF
#define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10)
#define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1)
#define C_000040_FP2_DETECT 0xFFFFFBFF
#define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11)
#define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1)
#define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF
#define S_000040_SCRATCH_INT_MASK(x) (((x) & 0x1) << 18)
#define G_000040_SCRATCH_INT_MASK(x) (((x) >> 18) & 0x1)
#define C_000040_SCRATCH_INT_MASK 0xFFFBFFFF
#define S_000040_GUI_IDLE_MASK(x) (((x) & 0x1) << 19)
#define G_000040_GUI_IDLE_MASK(x) (((x) >> 19) & 0x1)
#define C_000040_GUI_IDLE_MASK 0xFFF7FFFF
#define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13)
#define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1)
#define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF
370,8 → 355,91
#define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5)
#define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1)
#define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF
#define S_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 16)
#define G_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) >> 16) & 0x1)
#define C_007EDC_DACA_AUTODETECT_INTERRUPT 0xFFFEFFFF
#define S_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 17)
#define G_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) >> 17) & 0x1)
#define C_007EDC_DACB_AUTODETECT_INTERRUPT 0xFFFDFFFF
#define S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) & 0x1) << 18)
#define G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) >> 18) & 0x1)
#define C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT 0xFFFBFFFF
#define S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) & 0x1) << 19)
#define G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) >> 19) & 0x1)
#define C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT 0xFFF7FFFF
#define R_007828_DACA_AUTODETECT_CONTROL 0x007828
#define S_007828_DACA_AUTODETECT_MODE(x) (((x) & 0x3) << 0)
#define G_007828_DACA_AUTODETECT_MODE(x) (((x) >> 0) & 0x3)
#define C_007828_DACA_AUTODETECT_MODE 0xFFFFFFFC
#define S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8)
#define G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff)
#define C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF
#define S_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16)
#define G_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3)
#define C_007828_DACA_AUTODETECT_CHECK_MASK 0xFFFCFFFF
#define R_007838_DACA_AUTODETECT_INT_CONTROL 0x007838
#define S_007838_DACA_AUTODETECT_ACK(x) (((x) & 0x1) << 0)
#define C_007838_DACA_DACA_AUTODETECT_ACK 0xFFFFFFFE
#define S_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16)
#define G_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1)
#define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFCFFFF
#define R_007A28_DACB_AUTODETECT_CONTROL 0x007A28
#define S_007A28_DACB_AUTODETECT_MODE(x) (((x) & 0x3) << 0)
#define G_007A28_DACB_AUTODETECT_MODE(x) (((x) >> 0) & 0x3)
#define C_007A28_DACB_AUTODETECT_MODE 0xFFFFFFFC
#define S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8)
#define G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff)
#define C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF
#define S_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16)
#define G_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3)
#define C_007A28_DACB_AUTODETECT_CHECK_MASK 0xFFFCFFFF
#define R_007A38_DACB_AUTODETECT_INT_CONTROL 0x007A38
#define S_007A38_DACB_AUTODETECT_ACK(x) (((x) & 0x1) << 0)
#define C_007A38_DACB_DACA_AUTODETECT_ACK 0xFFFFFFFE
#define S_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16)
#define G_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1)
#define C_007A38_DACB_AUTODETECT_INT_ENABLE 0xFFFCFFFF
#define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL 0x007D00
#define S_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) & 0x1) << 0)
#define G_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) >> 0) & 0x1)
#define C_007D00_DC_HOT_PLUG_DETECT1_EN 0xFFFFFFFE
#define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0x007D04
#define S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) & 0x1) << 0)
#define G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) >> 0) & 0x1)
#define C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0xFFFFFFFE
#define S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) & 0x1) << 1)
#define G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) >> 1) & 0x1)
#define C_007D04_DC_HOT_PLUG_DETECT1_SENSE 0xFFFFFFFD
#define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL 0x007D08
#define S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x) (((x) & 0x1) << 0)
#define C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK 0xFFFFFFFE
#define S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8)
#define G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1)
#define C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY 0xFFFFFEFF
#define S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) & 0x1) << 16)
#define G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) >> 16) & 0x1)
#define C_007D08_DC_HOT_PLUG_DETECT1_INT_EN 0xFFFEFFFF
#define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL 0x007D10
#define S_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) & 0x1) << 0)
#define G_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) >> 0) & 0x1)
#define C_007D10_DC_HOT_PLUG_DETECT2_EN 0xFFFFFFFE
#define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0x007D14
#define S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) & 0x1) << 0)
#define G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) >> 0) & 0x1)
#define C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0xFFFFFFFE
#define S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) & 0x1) << 1)
#define G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) >> 1) & 0x1)
#define C_007D14_DC_HOT_PLUG_DETECT2_SENSE 0xFFFFFFFD
#define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL 0x007D18
#define S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x) (((x) & 0x1) << 0)
#define C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK 0xFFFFFFFE
#define S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8)
#define G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1)
#define C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY 0xFFFFFEFF
#define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16)
#define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1)
#define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF
 
 
/* MC registers */
#define R_000000_MC_STATUS 0x000000
#define S_000000_MC_IDLE(x) (((x) & 0x1) << 0)