Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/airlied/drm-2.6

* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/kms: teardown crtc correctly when fb is destroyed.
  drm/kms/radeon: cleanup combios TV table like DDX.
  drm/radeon/kms: memset the allocated framebuffer before using it.
  drm/radeon/kms: although LVDS might be possible on crtc 1 don't do it.
  drm/radeon/kms: implement bo busy check + current domain
  drm/radeon/kms: cut down indirects in register accesses.
  drm/radeon/kms: Fix up vertical blank interrupt support.
  drm/radeon/kms: add rv530 R300_SU_REG_DEST + reloc for ZPASS_ADDR
  drm/edid: fixup detailed timings like the X server.
  drm/radeon/kms: Add specific rs690 authorized register table
  • Loading branch information
Linus Torvalds committed Aug 19, 2009
2 parents 4aa2d56 + 5ef5f72 commit cad2c8f
Show file tree
Hide file tree
Showing 21 changed files with 456 additions and 254 deletions.
40 changes: 12 additions & 28 deletions drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,31 +257,6 @@ void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
}
EXPORT_SYMBOL(drm_mode_object_find);

/**
* drm_crtc_from_fb - find the CRTC structure associated with an fb
* @dev: DRM device
* @fb: framebuffer in question
*
* LOCKING:
* Caller must hold mode_config lock.
*
* Find CRTC in the mode_config structure that matches @fb.
*
* RETURNS:
* Pointer to the CRTC or NULL if it wasn't found.
*/
struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
struct drm_framebuffer *fb)
{
struct drm_crtc *crtc;

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb == fb)
return crtc;
}
return NULL;
}

/**
* drm_framebuffer_init - initialize a framebuffer
* @dev: DRM device
Expand Down Expand Up @@ -328,11 +303,20 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
struct drm_mode_set set;
int ret;

/* remove from any CRTC */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb == fb)
crtc->fb = NULL;
if (crtc->fb == fb) {
/* should turn off the crtc */
memset(&set, 0, sizeof(struct drm_mode_set));
set.crtc = crtc;
set.fb = NULL;
ret = crtc->funcs->set_config(&set);
if (ret)
DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
}
}

drm_mode_object_put(dev, &fb->base);
Expand Down Expand Up @@ -1511,7 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
set.mode = mode;
set.connectors = connector_set;
set.num_connectors = crtc_req->count_connectors;
set.fb =fb;
set.fb = fb;
ret = crtc->funcs->set_config(&set);

out:
Expand Down
72 changes: 34 additions & 38 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,40 @@ static int add_detailed_info(struct drm_connector *connector,
struct detailed_non_pixel *data = &timing->data.other_data;
struct drm_display_mode *newmode;

/* EDID up to and including 1.2 may put monitor info here */
if (edid->version == 1 && edid->revision < 3)
continue;

/* Detailed mode timing */
if (timing->pixel_clock) {
/* X server check is version 1.1 or higher */
if (edid->version == 1 && edid->revision >= 1 &&
!timing->pixel_clock) {
/* Other timing or info */
switch (data->type) {
case EDID_DETAIL_MONITOR_SERIAL:
break;
case EDID_DETAIL_MONITOR_STRING:
break;
case EDID_DETAIL_MONITOR_RANGE:
/* Get monitor range data */
break;
case EDID_DETAIL_MONITOR_NAME:
break;
case EDID_DETAIL_MONITOR_CPDATA:
break;
case EDID_DETAIL_STD_MODES:
/* Five modes per detailed section */
for (j = 0; j < 5; i++) {
struct std_timing *std;
struct drm_display_mode *newmode;

std = &data->data.timings[j];
newmode = drm_mode_std(dev, std);
if (newmode) {
drm_mode_probed_add(connector, newmode);
modes++;
}
}
break;
default:
break;
}
} else {
newmode = drm_mode_detailed(dev, edid, timing, quirks);
if (!newmode)
continue;
Expand All @@ -518,38 +546,6 @@ static int add_detailed_info(struct drm_connector *connector,
drm_mode_probed_add(connector, newmode);

modes++;
continue;
}

/* Other timing or info */
switch (data->type) {
case EDID_DETAIL_MONITOR_SERIAL:
break;
case EDID_DETAIL_MONITOR_STRING:
break;
case EDID_DETAIL_MONITOR_RANGE:
/* Get monitor range data */
break;
case EDID_DETAIL_MONITOR_NAME:
break;
case EDID_DETAIL_MONITOR_CPDATA:
break;
case EDID_DETAIL_STD_MODES:
/* Five modes per detailed section */
for (j = 0; j < 5; i++) {
struct std_timing *std;
struct drm_display_mode *newmode;

std = &data->data.timings[j];
newmode = drm_mode_std(dev, std);
if (newmode) {
drm_mode_probed_add(connector, newmode);
modes++;
}
}
break;
default:
break;
}
}

Expand Down
86 changes: 66 additions & 20 deletions drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,72 @@ void r100_mc_fini(struct radeon_device *rdev)
}


/*
* Interrupts
*/
int r100_irq_set(struct radeon_device *rdev)
{
uint32_t tmp = 0;

if (rdev->irq.sw_int) {
tmp |= RADEON_SW_INT_ENABLE;
}
if (rdev->irq.crtc_vblank_int[0]) {
tmp |= RADEON_CRTC_VBLANK_MASK;
}
if (rdev->irq.crtc_vblank_int[1]) {
tmp |= RADEON_CRTC2_VBLANK_MASK;
}
WREG32(RADEON_GEN_INT_CNTL, tmp);
return 0;
}

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;

if (irqs) {
WREG32(RADEON_GEN_INT_STATUS, irqs);
}
return irqs & irq_mask;
}

int r100_irq_process(struct radeon_device *rdev)
{
uint32_t status;

status = r100_irq_ack(rdev);
if (!status) {
return IRQ_NONE;
}
while (status) {
/* SW interrupt */
if (status & RADEON_SW_INT_TEST) {
radeon_fence_process(rdev);
}
/* Vertical blank interrupts */
if (status & RADEON_CRTC_VBLANK_STAT) {
drm_handle_vblank(rdev->ddev, 0);
}
if (status & RADEON_CRTC2_VBLANK_STAT) {
drm_handle_vblank(rdev->ddev, 1);
}
status = r100_irq_ack(rdev);
}
return IRQ_HANDLED;
}

u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc)
{
if (crtc == 0)
return RREG32(RADEON_CRTC_CRNT_FRAME);
else
return RREG32(RADEON_CRTC2_CRNT_FRAME);
}


/*
* Fence emission
*/
Expand Down Expand Up @@ -1556,26 +1622,6 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
r100_pll_errata_after_data(rdev);
}

uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg)
{
if (reg < 0x10000)
return readl(((void __iomem *)rdev->rmmio) + reg);
else {
writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
}
}

void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
if (reg < 0x10000)
writel(v, ((void __iomem *)rdev->rmmio) + reg);
else {
writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
}
}

int r100_init(struct radeon_device *rdev)
{
return 0;
Expand Down
38 changes: 16 additions & 22 deletions drivers/gpu/drm/radeon/r300.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB);
(void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
mb();
}
mb();
}

int rv370_pcie_gart_enable(struct radeon_device *rdev)
Expand Down Expand Up @@ -592,27 +592,6 @@ void r300_vram_info(struct radeon_device *rdev)
}


/*
* Indirect registers accessor
*/
uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg)
{
uint32_t r;

WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff));
(void)RREG32(RADEON_PCIE_INDEX);
r = RREG32(RADEON_PCIE_DATA);
return r;
}

void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff));
(void)RREG32(RADEON_PCIE_INDEX);
WREG32(RADEON_PCIE_DATA, (v));
(void)RREG32(RADEON_PCIE_DATA);
}

/*
* PCIE Lanes
*/
Expand Down Expand Up @@ -1403,6 +1382,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
tmp = (ib_chunk->kdata[idx] >> 22) & 0xF;
track->textures[i].txdepth = tmp;
break;
case R300_ZB_ZPASS_ADDR:
r = r100_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
idx, reg);
r100_cs_dump_packet(p, pkt);
return r;
}
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
break;
case 0x4be8:
/* valid register only on RV530 */
if (p->rdev->family == CHIP_RV530)
break;
/* fallthrough do not move */
default:
printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
reg, idx);
Expand Down
16 changes: 12 additions & 4 deletions drivers/gpu/drm/radeon/r500_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@
#define AVIVO_D1CRTC_BLANK_CONTROL 0x6084
#define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088
#define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c
#define AVIVO_D1CRTC_FRAME_COUNT 0x60a4
#define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4

/* master controls */
Expand Down Expand Up @@ -438,14 +439,15 @@
# define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4
# define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff

#define R500_DxMODE_INT_MASK 0x6540
#define R500_D1MODE_INT_MASK (1<<0)
#define R500_D2MODE_INT_MASK (1<<8)

#define AVIVO_D1MODE_DATA_FORMAT 0x6528
# define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0)
#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C
#define AVIVO_D1MODE_VBLANK_STATUS 0x6534
# define AVIVO_VBLANK_ACK (1 << 4)
#define AVIVO_D1MODE_VLINE_START_END 0x6538
#define AVIVO_DxMODE_INT_MASK 0x6540
# define AVIVO_D1MODE_INT_MASK (1 << 0)
# define AVIVO_D2MODE_INT_MASK (1 << 8)
#define AVIVO_D1MODE_VIEWPORT_START 0x6580
#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584
#define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588
Expand Down Expand Up @@ -475,6 +477,7 @@
#define AVIVO_D2CRTC_BLANK_CONTROL 0x6884
#define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888
#define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c
#define AVIVO_D2CRTC_FRAME_COUNT 0x68a4
#define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4

#define AVIVO_D2GRPH_ENABLE 0x6900
Expand All @@ -497,6 +500,7 @@
#define AVIVO_D2CUR_SIZE 0x6c10
#define AVIVO_D2CUR_POSITION 0x6c14

#define AVIVO_D2MODE_VBLANK_STATUS 0x6d34
#define AVIVO_D2MODE_VLINE_START_END 0x6d38
#define AVIVO_D2MODE_VIEWPORT_START 0x6d80
#define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84
Expand Down Expand Up @@ -748,4 +752,8 @@
# define AVIVO_I2C_EN (1 << 0)
# define AVIVO_I2C_RESET (1 << 8)

#define AVIVO_DISP_INTERRUPT_STATUS 0x7edc
# define AVIVO_D1_VBLANK_INTERRUPT (1 << 4)
# define AVIVO_D2_VBLANK_INTERRUPT (1 << 5)

#endif
Loading

0 comments on commit cad2c8f

Please sign in to comment.