Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: Add general-purpose packet for manipulating scratch registers (r300)

From: Aapo Tahkola (via DRM CVS)
Signed-off-by: Dave Airlie <airlied@linux.ie>

+75 -1
+67
drivers/char/drm/r300_cmdbuf.c
··· 704 704 buf->used = 0; 705 705 } 706 706 707 + static int r300_scratch(drm_radeon_private_t *dev_priv, 708 + drm_radeon_kcmd_buffer_t *cmdbuf, 709 + drm_r300_cmd_header_t header) 710 + { 711 + u32 *ref_age_base; 712 + u32 i, buf_idx, h_pending; 713 + RING_LOCALS; 714 + 715 + if (cmdbuf->bufsz < 716 + (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) { 717 + return DRM_ERR(EINVAL); 718 + } 719 + 720 + if (header.scratch.reg >= 5) { 721 + return DRM_ERR(EINVAL); 722 + } 723 + 724 + dev_priv->scratch_ages[header.scratch.reg]++; 725 + 726 + ref_age_base = *(u32 **)cmdbuf->buf; 727 + 728 + cmdbuf->buf += sizeof(u64); 729 + cmdbuf->bufsz -= sizeof(u64); 730 + 731 + for (i=0; i < header.scratch.n_bufs; i++) { 732 + buf_idx = *(u32 *)cmdbuf->buf; 733 + buf_idx *= 2; /* 8 bytes per buf */ 734 + 735 + if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) { 736 + return DRM_ERR(EINVAL); 737 + } 738 + 739 + if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) { 740 + return DRM_ERR(EINVAL); 741 + } 742 + 743 + if (h_pending == 0) { 744 + return DRM_ERR(EINVAL); 745 + } 746 + 747 + h_pending--; 748 + 749 + if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) { 750 + return DRM_ERR(EINVAL); 751 + } 752 + 753 + cmdbuf->buf += sizeof(buf_idx); 754 + cmdbuf->bufsz -= sizeof(buf_idx); 755 + } 756 + 757 + BEGIN_RING(2); 758 + OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0)); 759 + OUT_RING(dev_priv->scratch_ages[header.scratch.reg]); 760 + ADVANCE_RING(); 761 + 762 + return 0; 763 + } 764 + 707 765 /** 708 766 * Parses and validates a user-supplied command buffer and emits appropriate 709 767 * commands on the DMA ring buffer. ··· 899 841 } 900 842 break; 901 843 844 + case R300_CMD_SCRATCH: 845 + DRM_DEBUG("R300_CMD_SCRATCH\n"); 846 + ret = r300_scratch(dev_priv, cmdbuf, header); 847 + if (ret) { 848 + DRM_ERROR("r300_scratch failed\n"); 849 + goto cleanup; 850 + } 851 + break; 852 + 902 853 default: 903 854 DRM_ERROR("bad cmd_type %i at %p\n", 904 855 header.header.cmd_type,
+4
drivers/char/drm/radeon_drm.h
··· 222 222 # define R300_WAIT_3D 0x2 223 223 # define R300_WAIT_2D_CLEAN 0x3 224 224 # define R300_WAIT_3D_CLEAN 0x4 225 + #define R300_CMD_SCRATCH 8 225 226 226 227 typedef union { 227 228 unsigned int u; ··· 248 247 struct { 249 248 unsigned char cmd_type, flags, pad0, pad1; 250 249 } wait; 250 + struct { 251 + unsigned char cmd_type, reg, n_bufs, flags; 252 + } scratch; 251 253 } drm_r300_cmd_header_t; 252 254 253 255 #define RADEON_FRONT 0x1
+4 -1
drivers/char/drm/radeon_drv.h
··· 92 92 * 1.21- Add support for card type getparam 93 93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL) 94 94 * 1.23- Add new radeon memory map work from benh 95 + * 1.24- Add general-purpose packet for manipulating scratch registers (r300) 95 96 */ 96 97 #define DRIVER_MAJOR 1 97 - #define DRIVER_MINOR 23 98 + #define DRIVER_MINOR 24 98 99 #define DRIVER_PATCHLEVEL 0 99 100 100 101 /* ··· 276 275 277 276 unsigned long pcigart_offset; 278 277 drm_ati_pcigart_info gart_info; 278 + 279 + u32 scratch_ages[5]; 279 280 280 281 /* starting from here on, data is preserved accross an open */ 281 282 uint32_t flags; /* see radeon_chip_flags */