diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 87 |
1 files changed, 61 insertions, 26 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 5f15820efe12..e372f9e1e5ce 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -70,23 +70,6 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
70 | 70 | ||
71 | void r100_pre_page_flip(struct radeon_device *rdev, int crtc) | 71 | void r100_pre_page_flip(struct radeon_device *rdev, int crtc) |
72 | { | 72 | { |
73 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
74 | u32 tmp; | ||
75 | |||
76 | /* make sure flip is at vb rather than hb */ | ||
77 | tmp = RREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset); | ||
78 | tmp &= ~RADEON_CRTC_OFFSET_FLIP_CNTL; | ||
79 | /* make sure pending bit is asserted */ | ||
80 | tmp |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN; | ||
81 | WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, tmp); | ||
82 | |||
83 | /* set pageflip to happen as late as possible in the vblank interval. | ||
84 | * same field for crtc1/2 | ||
85 | */ | ||
86 | tmp = RREG32(RADEON_CRTC_GEN_CNTL); | ||
87 | tmp &= ~RADEON_CRTC_VSTAT_MODE_MASK; | ||
88 | WREG32(RADEON_CRTC_GEN_CNTL, tmp); | ||
89 | |||
90 | /* enable the pflip int */ | 73 | /* enable the pflip int */ |
91 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | 74 | radeon_irq_kms_pflip_irq_get(rdev, crtc); |
92 | } | 75 | } |
@@ -1041,7 +1024,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
1041 | return r; | 1024 | return r; |
1042 | } | 1025 | } |
1043 | rdev->cp.ready = true; | 1026 | rdev->cp.ready = true; |
1044 | rdev->mc.active_vram_size = rdev->mc.real_vram_size; | 1027 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
1045 | return 0; | 1028 | return 0; |
1046 | } | 1029 | } |
1047 | 1030 | ||
@@ -1059,7 +1042,7 @@ void r100_cp_fini(struct radeon_device *rdev) | |||
1059 | void r100_cp_disable(struct radeon_device *rdev) | 1042 | void r100_cp_disable(struct radeon_device *rdev) |
1060 | { | 1043 | { |
1061 | /* Disable ring */ | 1044 | /* Disable ring */ |
1062 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1045 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
1063 | rdev->cp.ready = false; | 1046 | rdev->cp.ready = false; |
1064 | WREG32(RADEON_CP_CSQ_MODE, 0); | 1047 | WREG32(RADEON_CP_CSQ_MODE, 0); |
1065 | WREG32(RADEON_CP_CSQ_CNTL, 0); | 1048 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
@@ -1427,6 +1410,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1427 | } | 1410 | } |
1428 | track->zb.robj = reloc->robj; | 1411 | track->zb.robj = reloc->robj; |
1429 | track->zb.offset = idx_value; | 1412 | track->zb.offset = idx_value; |
1413 | track->zb_dirty = true; | ||
1430 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1414 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1431 | break; | 1415 | break; |
1432 | case RADEON_RB3D_COLOROFFSET: | 1416 | case RADEON_RB3D_COLOROFFSET: |
@@ -1439,6 +1423,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1439 | } | 1423 | } |
1440 | track->cb[0].robj = reloc->robj; | 1424 | track->cb[0].robj = reloc->robj; |
1441 | track->cb[0].offset = idx_value; | 1425 | track->cb[0].offset = idx_value; |
1426 | track->cb_dirty = true; | ||
1442 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1427 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1443 | break; | 1428 | break; |
1444 | case RADEON_PP_TXOFFSET_0: | 1429 | case RADEON_PP_TXOFFSET_0: |
@@ -1454,6 +1439,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1454 | } | 1439 | } |
1455 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1440 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1456 | track->textures[i].robj = reloc->robj; | 1441 | track->textures[i].robj = reloc->robj; |
1442 | track->tex_dirty = true; | ||
1457 | break; | 1443 | break; |
1458 | case RADEON_PP_CUBIC_OFFSET_T0_0: | 1444 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
1459 | case RADEON_PP_CUBIC_OFFSET_T0_1: | 1445 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
@@ -1471,6 +1457,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1471 | track->textures[0].cube_info[i].offset = idx_value; | 1457 | track->textures[0].cube_info[i].offset = idx_value; |
1472 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1458 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1473 | track->textures[0].cube_info[i].robj = reloc->robj; | 1459 | track->textures[0].cube_info[i].robj = reloc->robj; |
1460 | track->tex_dirty = true; | ||
1474 | break; | 1461 | break; |
1475 | case RADEON_PP_CUBIC_OFFSET_T1_0: | 1462 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
1476 | case RADEON_PP_CUBIC_OFFSET_T1_1: | 1463 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
@@ -1488,6 +1475,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1488 | track->textures[1].cube_info[i].offset = idx_value; | 1475 | track->textures[1].cube_info[i].offset = idx_value; |
1489 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1476 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1490 | track->textures[1].cube_info[i].robj = reloc->robj; | 1477 | track->textures[1].cube_info[i].robj = reloc->robj; |
1478 | track->tex_dirty = true; | ||
1491 | break; | 1479 | break; |
1492 | case RADEON_PP_CUBIC_OFFSET_T2_0: | 1480 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
1493 | case RADEON_PP_CUBIC_OFFSET_T2_1: | 1481 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
@@ -1505,9 +1493,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1505 | track->textures[2].cube_info[i].offset = idx_value; | 1493 | track->textures[2].cube_info[i].offset = idx_value; |
1506 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1494 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1507 | track->textures[2].cube_info[i].robj = reloc->robj; | 1495 | track->textures[2].cube_info[i].robj = reloc->robj; |
1496 | track->tex_dirty = true; | ||
1508 | break; | 1497 | break; |
1509 | case RADEON_RE_WIDTH_HEIGHT: | 1498 | case RADEON_RE_WIDTH_HEIGHT: |
1510 | track->maxy = ((idx_value >> 16) & 0x7FF); | 1499 | track->maxy = ((idx_value >> 16) & 0x7FF); |
1500 | track->cb_dirty = true; | ||
1501 | track->zb_dirty = true; | ||
1511 | break; | 1502 | break; |
1512 | case RADEON_RB3D_COLORPITCH: | 1503 | case RADEON_RB3D_COLORPITCH: |
1513 | r = r100_cs_packet_next_reloc(p, &reloc); | 1504 | r = r100_cs_packet_next_reloc(p, &reloc); |
@@ -1528,9 +1519,11 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1528 | ib[idx] = tmp; | 1519 | ib[idx] = tmp; |
1529 | 1520 | ||
1530 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; | 1521 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
1522 | track->cb_dirty = true; | ||
1531 | break; | 1523 | break; |
1532 | case RADEON_RB3D_DEPTHPITCH: | 1524 | case RADEON_RB3D_DEPTHPITCH: |
1533 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; | 1525 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
1526 | track->zb_dirty = true; | ||
1534 | break; | 1527 | break; |
1535 | case RADEON_RB3D_CNTL: | 1528 | case RADEON_RB3D_CNTL: |
1536 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { | 1529 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
@@ -1555,6 +1548,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1555 | return -EINVAL; | 1548 | return -EINVAL; |
1556 | } | 1549 | } |
1557 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); | 1550 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
1551 | track->cb_dirty = true; | ||
1552 | track->zb_dirty = true; | ||
1558 | break; | 1553 | break; |
1559 | case RADEON_RB3D_ZSTENCILCNTL: | 1554 | case RADEON_RB3D_ZSTENCILCNTL: |
1560 | switch (idx_value & 0xf) { | 1555 | switch (idx_value & 0xf) { |
@@ -1572,6 +1567,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1572 | default: | 1567 | default: |
1573 | break; | 1568 | break; |
1574 | } | 1569 | } |
1570 | track->zb_dirty = true; | ||
1575 | break; | 1571 | break; |
1576 | case RADEON_RB3D_ZPASS_ADDR: | 1572 | case RADEON_RB3D_ZPASS_ADDR: |
1577 | r = r100_cs_packet_next_reloc(p, &reloc); | 1573 | r = r100_cs_packet_next_reloc(p, &reloc); |
@@ -1588,6 +1584,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1588 | uint32_t temp = idx_value >> 4; | 1584 | uint32_t temp = idx_value >> 4; |
1589 | for (i = 0; i < track->num_texture; i++) | 1585 | for (i = 0; i < track->num_texture; i++) |
1590 | track->textures[i].enabled = !!(temp & (1 << i)); | 1586 | track->textures[i].enabled = !!(temp & (1 << i)); |
1587 | track->tex_dirty = true; | ||
1591 | } | 1588 | } |
1592 | break; | 1589 | break; |
1593 | case RADEON_SE_VF_CNTL: | 1590 | case RADEON_SE_VF_CNTL: |
@@ -1602,12 +1599,14 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1602 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; | 1599 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
1603 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; | 1600 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
1604 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; | 1601 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
1602 | track->tex_dirty = true; | ||
1605 | break; | 1603 | break; |
1606 | case RADEON_PP_TEX_PITCH_0: | 1604 | case RADEON_PP_TEX_PITCH_0: |
1607 | case RADEON_PP_TEX_PITCH_1: | 1605 | case RADEON_PP_TEX_PITCH_1: |
1608 | case RADEON_PP_TEX_PITCH_2: | 1606 | case RADEON_PP_TEX_PITCH_2: |
1609 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; | 1607 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
1610 | track->textures[i].pitch = idx_value + 32; | 1608 | track->textures[i].pitch = idx_value + 32; |
1609 | track->tex_dirty = true; | ||
1611 | break; | 1610 | break; |
1612 | case RADEON_PP_TXFILTER_0: | 1611 | case RADEON_PP_TXFILTER_0: |
1613 | case RADEON_PP_TXFILTER_1: | 1612 | case RADEON_PP_TXFILTER_1: |
@@ -1621,6 +1620,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1621 | tmp = (idx_value >> 27) & 0x7; | 1620 | tmp = (idx_value >> 27) & 0x7; |
1622 | if (tmp == 2 || tmp == 6) | 1621 | if (tmp == 2 || tmp == 6) |
1623 | track->textures[i].roundup_h = false; | 1622 | track->textures[i].roundup_h = false; |
1623 | track->tex_dirty = true; | ||
1624 | break; | 1624 | break; |
1625 | case RADEON_PP_TXFORMAT_0: | 1625 | case RADEON_PP_TXFORMAT_0: |
1626 | case RADEON_PP_TXFORMAT_1: | 1626 | case RADEON_PP_TXFORMAT_1: |
@@ -1673,6 +1673,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1673 | } | 1673 | } |
1674 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); | 1674 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
1675 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); | 1675 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
1676 | track->tex_dirty = true; | ||
1676 | break; | 1677 | break; |
1677 | case RADEON_PP_CUBIC_FACES_0: | 1678 | case RADEON_PP_CUBIC_FACES_0: |
1678 | case RADEON_PP_CUBIC_FACES_1: | 1679 | case RADEON_PP_CUBIC_FACES_1: |
@@ -1683,6 +1684,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1683 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); | 1684 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
1684 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); | 1685 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
1685 | } | 1686 | } |
1687 | track->tex_dirty = true; | ||
1686 | break; | 1688 | break; |
1687 | default: | 1689 | default: |
1688 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 1690 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
@@ -2310,7 +2312,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev) | |||
2310 | /* FIXME we don't use the second aperture yet when we could use it */ | 2312 | /* FIXME we don't use the second aperture yet when we could use it */ |
2311 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) | 2313 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) |
2312 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 2314 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
2313 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
2314 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); | 2315 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); |
2315 | if (rdev->flags & RADEON_IS_IGP) { | 2316 | if (rdev->flags & RADEON_IS_IGP) { |
2316 | uint32_t tom; | 2317 | uint32_t tom; |
@@ -3318,9 +3319,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3318 | unsigned long size; | 3319 | unsigned long size; |
3319 | unsigned prim_walk; | 3320 | unsigned prim_walk; |
3320 | unsigned nverts; | 3321 | unsigned nverts; |
3321 | unsigned num_cb = track->num_cb; | 3322 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; |
3322 | 3323 | ||
3323 | if (!track->zb_cb_clear && !track->color_channel_mask && | 3324 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && |
3324 | !track->blend_read_enable) | 3325 | !track->blend_read_enable) |
3325 | num_cb = 0; | 3326 | num_cb = 0; |
3326 | 3327 | ||
@@ -3341,7 +3342,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3341 | return -EINVAL; | 3342 | return -EINVAL; |
3342 | } | 3343 | } |
3343 | } | 3344 | } |
3344 | if (track->z_enabled) { | 3345 | track->cb_dirty = false; |
3346 | |||
3347 | if (track->zb_dirty && track->z_enabled) { | ||
3345 | if (track->zb.robj == NULL) { | 3348 | if (track->zb.robj == NULL) { |
3346 | DRM_ERROR("[drm] No buffer for z buffer !\n"); | 3349 | DRM_ERROR("[drm] No buffer for z buffer !\n"); |
3347 | return -EINVAL; | 3350 | return -EINVAL; |
@@ -3358,6 +3361,28 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3358 | return -EINVAL; | 3361 | return -EINVAL; |
3359 | } | 3362 | } |
3360 | } | 3363 | } |
3364 | track->zb_dirty = false; | ||
3365 | |||
3366 | if (track->aa_dirty && track->aaresolve) { | ||
3367 | if (track->aa.robj == NULL) { | ||
3368 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); | ||
3369 | return -EINVAL; | ||
3370 | } | ||
3371 | /* I believe the format comes from colorbuffer0. */ | ||
3372 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; | ||
3373 | size += track->aa.offset; | ||
3374 | if (size > radeon_bo_size(track->aa.robj)) { | ||
3375 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " | ||
3376 | "(need %lu have %lu) !\n", i, size, | ||
3377 | radeon_bo_size(track->aa.robj)); | ||
3378 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", | ||
3379 | i, track->aa.pitch, track->cb[0].cpp, | ||
3380 | track->aa.offset, track->maxy); | ||
3381 | return -EINVAL; | ||
3382 | } | ||
3383 | } | ||
3384 | track->aa_dirty = false; | ||
3385 | |||
3361 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; | 3386 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
3362 | if (track->vap_vf_cntl & (1 << 14)) { | 3387 | if (track->vap_vf_cntl & (1 << 14)) { |
3363 | nverts = track->vap_alt_nverts; | 3388 | nverts = track->vap_alt_nverts; |
@@ -3417,13 +3442,23 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3417 | prim_walk); | 3442 | prim_walk); |
3418 | return -EINVAL; | 3443 | return -EINVAL; |
3419 | } | 3444 | } |
3420 | return r100_cs_track_texture_check(rdev, track); | 3445 | |
3446 | if (track->tex_dirty) { | ||
3447 | track->tex_dirty = false; | ||
3448 | return r100_cs_track_texture_check(rdev, track); | ||
3449 | } | ||
3450 | return 0; | ||
3421 | } | 3451 | } |
3422 | 3452 | ||
3423 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) | 3453 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) |
3424 | { | 3454 | { |
3425 | unsigned i, face; | 3455 | unsigned i, face; |
3426 | 3456 | ||
3457 | track->cb_dirty = true; | ||
3458 | track->zb_dirty = true; | ||
3459 | track->tex_dirty = true; | ||
3460 | track->aa_dirty = true; | ||
3461 | |||
3427 | if (rdev->family < CHIP_R300) { | 3462 | if (rdev->family < CHIP_R300) { |
3428 | track->num_cb = 1; | 3463 | track->num_cb = 1; |
3429 | if (rdev->family <= CHIP_RS200) | 3464 | if (rdev->family <= CHIP_RS200) |
@@ -3437,6 +3472,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track | |||
3437 | track->num_texture = 16; | 3472 | track->num_texture = 16; |
3438 | track->maxy = 4096; | 3473 | track->maxy = 4096; |
3439 | track->separate_cube = 0; | 3474 | track->separate_cube = 0; |
3475 | track->aaresolve = false; | ||
3476 | track->aa.robj = NULL; | ||
3440 | } | 3477 | } |
3441 | 3478 | ||
3442 | for (i = 0; i < track->num_cb; i++) { | 3479 | for (i = 0; i < track->num_cb; i++) { |
@@ -3746,8 +3783,6 @@ static int r100_startup(struct radeon_device *rdev) | |||
3746 | r100_mc_program(rdev); | 3783 | r100_mc_program(rdev); |
3747 | /* Resume clock */ | 3784 | /* Resume clock */ |
3748 | r100_clock_startup(rdev); | 3785 | r100_clock_startup(rdev); |
3749 | /* Initialize GPU configuration (# pipes, ...) */ | ||
3750 | // r100_gpu_init(rdev); | ||
3751 | /* Initialize GART (initialize after TTM so we can allocate | 3786 | /* Initialize GART (initialize after TTM so we can allocate |
3752 | * memory through TTM but finalize after TTM) */ | 3787 | * memory through TTM but finalize after TTM) */ |
3753 | r100_enable_bm(rdev); | 3788 | r100_enable_bm(rdev); |