aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/evergreen_cs.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-10-03 10:32:58 +1000
committerDave Airlie <airlied@redhat.com>2012-10-03 10:32:58 +1000
commit8ff1f792dd68ad46f3cfe01e01a375b402cf08da (patch)
treeb73b4fa71c5a9357931360d7894beee247cd464e /drivers/gpu/drm/radeon/evergreen_cs.c
parent2216c9e74fb3baac3cb73952158dbe38b703997e (diff)
parent82ffd92b162ece87c863c075d993c65333e8e78b (diff)
Merge branch 'drm-next-3.7' of git://people.freedesktop.org/~agd5f/linux into drm-next
Alex writes: "The big changes for 3.7 include: - Asynchronous VM page table updates for Cayman/SI - 2 level VM page table support. Saves memory compared to 1 level page tables. - Reworked PLL handing in the display code allows lots more combinations of monitors to work, including more than two DP displays assuming compatible clocks across shared PLLs. This also allows us to power down extra PLLs when we can share a single one across multiple displays which saves power. - Native backlight control on ATOMBIOS systems. - Improved ACPI support for interacting with the GPU. Fixes backlight control on some laptops. - Document AMD ACPI interfaces - Lots of code cleanup - Bug fixes" * 'drm-next-3.7' of git://people.freedesktop.org/~agd5f/linux: (79 commits) drm/radeon: add vm set_page() callback for SI drm/radeon: rework the vm_flush interface drm/radeon: use WRITE_DATA packets for vm flush on SI drm/radeon/pm: fix multi-head profile handling on BTC+ (v2) drm/radeon: fix radeon power state debug output drm/radeon: force MSIs on RS690 asics drm/radeon: Add MSI quirk for gateway RS690 drm/radeon: allow MIP_ADDRESS=0 for MSAA textures on Evergreen drm/radeon/kms: allow STRMOUT_BASE_UPDATE on RS780 and RS880 drm/radeon: add 2-level VM pagetables support v9 drm/radeon: refactor set_page chipset interface v5 drm/radeon: Fix scratch register leak in IB test. drm/radeon: restore backlight level on resume drm/radeon: add get_backlight_level callback drm/radeon: only adjust default clocks on NI GPUs drm/radeon: validate PPLL in crtc fixup drm/radeon: work around KMS modeset limitations in PLL allocation (v2) drm/radeon: make non-DP PPLL sharing more robust drm/radeon: store the encoder in the radeon_crtc drm/radeon: rework crtc pll setup to better support PPLL sharing ...
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index e44a62a07fe..2ceab2b52d6 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -846,6 +846,16 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
return -EINVAL;
}
+ if (!mipmap) {
+ if (llevel) {
+ dev_warn(p->dev, "%s:%i got NULL MIP_ADDRESS relocation\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ } else {
+ return 0; /* everything's ok */
+ }
+ }
+
/* check mipmap size */
for (i = 1; i <= llevel; i++) {
unsigned w, h, d;
@@ -995,7 +1005,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
* Assume that chunk_ib_index is properly set. Will return -EINVAL
* if packet is bigger than remaining ib size. or if packets is unknown.
**/
-int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
+static int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx)
{
@@ -1081,6 +1091,27 @@ static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
}
/**
+ * evergreen_cs_packet_next_is_pkt3_nop() - test if the next packet is NOP
+ * @p: structure holding the parser context.
+ *
+ * Check if the next packet is a relocation packet3.
+ **/
+static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
+{
+ struct radeon_cs_packet p3reloc;
+ int r;
+
+ r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
+ if (r) {
+ return false;
+ }
+ if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+ return false;
+ }
+ return true;
+}
+
+/**
* evergreen_cs_packet_next_vline() - parse userspace VLINE packet
* @parser: parser structure holding parsing context.
*
@@ -2330,7 +2361,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
for (i = 0; i < (pkt->count / 8); i++) {
struct radeon_bo *texture, *mipmap;
u32 toffset, moffset;
- u32 size, offset;
+ u32 size, offset, mip_address, tex_dim;
switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
case SQ_TEX_VTX_VALID_TEXTURE:
@@ -2359,14 +2390,28 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
}
texture = reloc->robj;
toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+
/* tex mip base */
- r = evergreen_cs_packet_next_reloc(p, &reloc);
- if (r) {
- DRM_ERROR("bad SET_RESOURCE (tex)\n");
- return -EINVAL;
+ tex_dim = ib[idx+1+(i*8)+0] & 0x7;
+ mip_address = ib[idx+1+(i*8)+3];
+
+ if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) &&
+ !mip_address &&
+ !evergreen_cs_packet_next_is_pkt3_nop(p)) {
+ /* MIP_ADDRESS should point to FMASK for an MSAA texture.
+ * It should be 0 if FMASK is disabled. */
+ moffset = 0;
+ mipmap = NULL;
+ } else {
+ r = evergreen_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad SET_RESOURCE (tex)\n");
+ return -EINVAL;
+ }
+ moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+ mipmap = reloc->robj;
}
- moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
- mipmap = reloc->robj;
+
r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8));
if (r)
return r;