X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fchar%2Fdrm%2Fvia_verifier.c;h=46a57919874797b3b41d694b1ab70159a6f3e13e;hb=8d3c202be23c5a915f7053ebd4e96f44700c6a62;hp=70c897c8876643313e3093b1360e6f1c0cf1e92e;hpb=94bc2be31a01a3055ec94176e595dfe208e92d3b;p=linux-2.6 diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c index 70c897c887..46a5791987 100644 --- a/drivers/char/drm/via_verifier.c +++ b/drivers/char/drm/via_verifier.c @@ -252,10 +252,9 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, unsigned long offset, unsigned long size, - drm_device_t * dev) + struct drm_device * dev) { - struct list_head *list; - drm_map_list_t *r_list; + struct drm_map_list *r_list; drm_local_map_t *map = seq->map_cache; if (map && map->offset <= offset @@ -263,8 +262,7 @@ static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, return map; } - list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *) list; + list_for_each_entry(r_list, &dev->maplist, head) { map = r_list->map; if (!map) continue; @@ -306,6 +304,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) unsigned long lo = ~0, hi = 0, tmp; uint32_t *addr, *pitch, *height, tex; unsigned i; + int npot; if (end > 9) end = 9; @@ -316,12 +315,15 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) &(cur_seq->t_addr[tex = cur_seq->texture][start]); pitch = &(cur_seq->pitch[tex][start]); height = &(cur_seq->height[tex][start]); - + npot = cur_seq->tex_npot[tex]; for (i = start; i <= end; ++i) { tmp = *addr++; if (tmp < lo) lo = tmp; - tmp += (*height++ << *pitch++); + if (i == 0 && npot) + tmp += (*height++ * *pitch++); + else + tmp += (*height++ << *pitch++); if (tmp > hi) hi = tmp; } @@ -443,13 +445,21 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) return 0; case check_texture_addr3: cur_seq->unfinished = tex_address; - tmp = ((cmd >> 24) - 0x2B); - cur_seq->pitch[cur_seq->texture][tmp] = - (cmd & 0x00F00000) >> 20; - if (!tmp && (cmd & 0x000FFFFF)) { - DRM_ERROR - ("Unimplemented texture level 0 pitch mode.\n"); - return 2; + tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit); + if (tmp == 0 && + (cmd & HC_HTXnEnPit_MASK)) { + cur_seq->pitch[cur_seq->texture][tmp] = + (cmd & HC_HTXnLnPit_MASK); + cur_seq->tex_npot[cur_seq->texture] = 1; + } else { + cur_seq->pitch[cur_seq->texture][tmp] = + (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT; + cur_seq->tex_npot[cur_seq->texture] = 0; + if (cmd & 0x000FFFFF) { + DRM_ERROR + ("Unimplemented texture level 0 pitch mode.\n"); + return 2; + } } return 0; case check_texture_addr4: @@ -952,7 +962,7 @@ via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer, int via_verify_command_stream(const uint32_t * buf, unsigned int size, - drm_device_t * dev, int agp) + struct drm_device * dev, int agp) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; @@ -961,7 +971,13 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, uint32_t cmd; const uint32_t *buf_end = buf + (size >> 2); verifier_state_t state = state_command; - int pro_group_a = dev_priv->pro_group_a; + int cme_video; + int supported_3d; + + cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A || + dev_priv->chipset == VIA_DX9_0); + + supported_3d = dev_priv->chipset != VIA_DX9_0; hc_state->dev = dev; hc_state->unfinished = no_sequence; @@ -986,17 +1002,21 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, state = via_check_vheader6(&buf, buf_end); break; case state_command: - if (HALCYON_HEADER2 == (cmd = *buf)) + if ((HALCYON_HEADER2 == (cmd = *buf)) && + supported_3d) state = state_header2; else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) state = state_header1; - else if (pro_group_a + else if (cme_video && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) state = state_vheader5; - else if (pro_group_a + else if (cme_video && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) state = state_vheader6; - else { + else if ((cmd == HALCYON_HEADER2) && !supported_3d) { + DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n"); + state = state_error; + } else { DRM_ERROR ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", cmd); @@ -1006,18 +1026,18 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, case state_error: default: *hc_state = saved_state; - return DRM_ERR(EINVAL); + return -EINVAL; } } if (state == state_error) { *hc_state = saved_state; - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; } int -via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, +via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, unsigned int size) { @@ -1062,11 +1082,11 @@ via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, break; case state_error: default: - return DRM_ERR(EINVAL); + return -EINVAL; } } if (state == state_error) { - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; }